AppleScript Automator Mac プログラミング

バッテリー警告Automatorアプリに、しばらく放っておいてもらうオプションを増やした

作業時は、満タンでも電源に繋いでおきたい

ちょっと前にこんなAutomatorスクリプトを書きました。

 

MacBook Proのバッテリー残量を定期的に監視して過充電と電池切れを防いでくれるシェルスクリプトを作ったらcronで動かずに困った話

Macのバッテリー膨張を防ぐために一定量充電されたらACアダプタを外すように促し、一定以下に電池残量が減ったらACアダプタを繋ぐように促すスクリプトを作りました。画面中心にダイアログが出るので無視できないのが特徴です

続きを見る

 

スクリプトを作ったきっかけが、MacBook Proに電源を繋ぎっぱなしにしてバッテリーが膨張した件です。

新型コロナ状況下のApple StoreジーニアスバーでMacBook Proの修理を依頼した話

MacBook Pro 2015のバッテリーが膨張してしまったので、Apple Storeのジーニアスバーに行って交換修理をして貰いました。ついでにスピーカーの音割れも修理。新型コロナウイルスの影響でいつもとは違った感じでした

続きを見る

 

過充電を防ぐためにコンセントタイマーも導入してみました。

MacBook Proバッテリー膨張の再発防止にデジタルコンセントタイマーCT24Dを導入

MacBook Proの過充電によるバッテリー膨張の再発を防止するため、デジタルコンセントタイマーCT24Dを導入しました。ちょっと使い方に癖があるので備忘録として残します

続きを見る

 

警告スクリプトとコンセントタイマーの組み合わせで、過充電や過放電を防げるようになりました。

ただ、集中して作業している時にちょこちょこ警告されると正直うるさいんですよね。

MacBook Proに外部ディスプレイや多くの周辺機器を接続してフル稼働させていると、バッテリー消費が激しくて、すぐに低残量警告が出ます。最近のモデルは充電も速いのでまたすぐ残量80%まで充電完了して警告がでる、ということを繰り替えすことになりました。

 

面倒くさいw。

 

作業に集中している時は、過充電のことは気にせず電源を繋ぎっぱなしにしておきたいです。

というわけで、過充電警告のダイアログに選択肢を用意しておいて、しばらく放っておいてもらえるようにしました。

 

 

「3時間放置」ボタンをクリックするとしばらく過充電警告はでなくなります。残量が少ない警告は従来通りです。

これで必要以上にバッテリー管理に囚われることがなくなり、使い勝手が大きく向上しました。

 

AppleScriptの display dialog の戻り値は "button returned:xxxxxx"

 

このダイアログは、以下のシェルスクリプトで表示しています。

 command
osascript -e 'display dialog "腹八分目。電源を外して下さい" with icon caution buttons("3時間放置","外します")'

ボタンを押したときの戻り値は、それぞれ以下のようになります。

 command

button returned:外します

button returned:3時間放置

 

で、これをif文でチェックして、必要な情報を環境変数に書き込んで、次にcronで呼び出されたときに環境変数も見て警告の有無を決める、という算段でした。

が、環境変数はちょっと扱いが面倒なので設定ファイルを使うことにしました。HOMEにsuspend_batt_check_count.txtというファイルを作って、そこにカウンターの数値を記録しておきます。

放っておいて欲しい時にはここにカウンターを書き込み、カウンターがゼロになるまでは警告を出さないようにします。

"cronで定期実行するAutomatorアプリケーション内のスクリプト中で書き換える環境変数"というのが、かなりややこしいみたいなので、将来の課題ということで先送りしました

 

Automatorは複数のシェルスクリプトを重ねられるのが便利

Automatorでは、複数のシェルスクリプトを組み合わせて、stdinや引数で繋ぐことができます。

これを利用して、まず設定ファイルの有無とカウンターの数値を見て、確認が必要なら"CHECK_BATT"と出力するだけのスクリプトを書きました。

頭のいい人は全部まとめてスッキリ書くのでしょうが、私はブロック分けしないとこんがらがってしまいます。

 

  1. バッテリー駆動時はカウンターをゼロにして必ず残量をチェック
  2. 設定ファイル(suspend_batt_check_count.txt)の有無をチェック
  3. ファイルがあれば読み込んで変数countに格納、なければ"CHECK_BATT"と出力
  4. 0より大きければカウンターを減らして書き込み
  5. 0なら"CHECK_BATT"と出力
#充電を継続するオプションを追加

#バッテリー駆動時はカウンターをゼロにして必ず残量をチェック
ac_or_batt=`pmset -g batt | sed -nE '/Now/p' | sed -E 's/Now drawing from //' | sed -E "s/'//g"`
if [ "$ac_or_batt" = "Battery Power" ]; then
    echo 0 > $HOME/suspend_batt_check_count.txt
fi

if [ ! -f $HOME/suspend_batt_check_count.txt ]; then
    echo "CHECK_BATT"
else
    while read line
        do
  			count=$line
    done < $HOME/suspend_batt_check_count.txt
    if [ $(( count )) -gt 0 ]; then
        count=$((count-1))
        echo $count > $HOME/suspend_batt_check_count.txt
    else
        echo "CHECK_BATT"
    fi
fi

 

    ここは割とすんなり動いてくれました。

シェルスクリプトの文字列比較はスペースが含まれると上手くいかない?

後段は、以前作ったバッテリー残量チェックスクリプトに前段から渡された"CHECK_BATT"のチェック機能と、ダイアログのボタン選択によって、設定ファイルに書き込む処理を追加しました。

ひとつハマったのが、ダイアログの戻り値のチェックです。

前述のように、このダイアログのボタンを押すと

 

 command

button returned:外します

button returned:3時間放置

という値が返ってきます。

これを変数answerに入れてif文チェックしてもうまく動きません。

 html
if [ "$answer" = "button returned:3時間放置" ]; then

ずいぶん調べて分かったことは、どうやら比較する文字列の中にスペースがあると正しく判定できないようです。

しかも、テストした感じではスペースが含まれているとその他の内容とか条件設定に関係なく全部 "true"判定になっていました。おかげで原因の特定に凄く時間がかかりました。とほほ

そこで、sedで戻り値からスペースを除去してやったところ、ちゃんと動きました。

 

 html
answer=`osascript -e 'display dialog "腹八分目。電源を外して下さい" with icon caution buttons("3時間放置","外します")' | sed 's/ //g'`

2段目のコード全体はこんな感じ。ちょこちょこ入ってるechoはデバッグ用です。

 

echo "$1"
if [ "$1" = "CHECK_BATT" ]; then

    date  >> battery_log_mbp20118.txt
    pmset -g batt >> battery_log_mbp20118.txt
    batterry_rest=`pmset -g batt |  sed -E "/Now/d" |  sed -E "/Warning/d" |  sed -E "s/\(no estimate\)//" | sed  -E "s/^.*\)//g" | sed  -E "s/\%;.*$//g"`
    ac_or_batt=`pmset -g batt |  sed -nE '/Now/p' | sed -E  's/Now drawing from //' | sed -E "s/'//g"`
    echo 0 > $HOME/suspend_batt_check_count.txt

    if [ $(( batterry_rest  )) -lt 21 -a "$ac_or_batt" = "Battery Power" ]; 
        then osascript -e 'display dialog "バッテリー残量僅少。ACアダプタを繋いで下さい" with icon caution buttons("繋ぎます")'
    else
        if [ $(( batterry_rest  )) -gt 79 -a "$ac_or_batt" = "AC Power" ]; then 
            answer=`osascript -e 'display dialog "腹八分目。電源を外して下さい" with icon caution buttons("3時間放置","外します")'  |  sed 's/ //g'`
            echo "$answer"
            if [ "$answer" = "buttonreturned:3時間放置" ]; then
                echo 36 > $HOME/suspend_batt_check_count.txt
            else
                echo 0 > $HOME/suspend_batt_check_count.txt
            fi
        fi
    fi
fi

 

最終的なAutomatorアプリケーションの内容です。これをcrontabで定期的に呼び出しています。

 

 

 

 

【追記】OSのバージョンアップで使わなくなった

その後、OSをBig Surにアップグレード、OS標準でバッテリー保護機能が備わりました。この機能か使えるMacBook Pro(2018)ではコンセントタイマーを使わなくなりました。

MacOS Big Surにしたらバッテリー保護用のコンセントタイマーや監視アプリがいらなくなった

Macbook ProのOSをBig Surにアップグレードしたらバッテリー管理機能が有効になったので、バッテリー監視の自作アプリやコンセントタイマーが不要になりました

続きを見る

 

 

 

 

 

-AppleScript, Automator, Mac, プログラミング