rtcwake+cronでノートPCを定時にオンオフする

ここでは ノートPCを定時にオン・オフする方法、つまり:

毎日一定の時刻にPCを立ち上げ
特定のプログラムを走らせ
終わったら電源をオフにする

方法を 自分向けの備忘をかねて紹介します。

ここで「特定のプログラム」のイメージとしては

  1. 為替レートや株価などを自動取得1するとか、銀行から入出金明細書のCSVファイルをダウンロードするなどの 会計・経理的 なプログラム
  2. PCに接続されているウエッブカメラで畑の作物や花壇の花の成長を記録するなどの 定時監視的 なプログラム

などがあります。

PCの電源を入れっぱなしにできるのであれば、 crontabに書き込むだけで定時にプログラムを走らせることができます。

しかし、1日にわずかな時間だけ動かすプログラムのためにパソコンの電源を24時間入れっぱなしにするのはとても不経済です。

最近になって偶然 rtcwake というコマンドの存在を知りました。これを使えば、BIOSに復帰時間を設定する機能がない型落ちのノートPCでも、電源のオン・オフを制御しながら 会計・経理的プログラムも定時監視的プログラムも定時・自動取得が可能です。省エネと電気代の節約につながります。

動作環境

ハードウエアは型落ちの中古ノートPC= ThinkPad X230 2

CPU: Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz
DISK: 168G SSD
MEM: 8GB

OSは Ubuntu 18.04.6 LTS です。

cron+rtcwakeによる電源のオン・オフ管理

ノートPCをサーバー的に運用する際に、フタを開けたままだとキーボードにホコリがたまるし、場所ふさぎで じゃま です。そこで何はともあれ フタを閉めてもノートPCがスリープしない設定をしておきます。

設定方法は補足資料1(ノートPCのフタを閉じてもスリープさせない設定) を見てください。

イベントのスケジュール

1のようなスケジュールでノートPCの電源をオン・オフし、プログラムを起動するケースを例にとって説明します。

表 1: PC電源の定時オンオフとプログラム実行のスケジュール例
時刻 電源状態 備考
21:00 ONにする 前日の21:10に自動復帰時刻が予約してある
21:05 ON状態 当日の株価(終値)を取得
21:10 ONからスリープへ 翌日21:00の自動復帰を予約してスリープ(S3)させる

crontabの設定

rtcwakeスーパーユーザ で操作することが必要です。 $ sudo su してから # crontab -e でcrontabを編集します。

crontab(スーパーユーザ)

10 21 * * * /usr/sbin/rtcwake -m mem -t "$(date +\%s -d 'tomorrow 21:00')"
  • rtcwake で、自動復帰時刻を曜日に関わらず翌日の 21:00 分に設定

crontab(一般ユーザ)

05 21 * * 1-5 /MyHomeDir/bin/fetch-stock-prices.sh
  • 曜日の項を 1-5 にして月曜日から金曜日までの間だけ起動させます。 fetch-stock-prices.sh は持ち株の終値取得のスクリプト1です。

rtcwake の説明

上の例にそって rtcwake コマンドの基本的な設定について説明します。

モード設定

-m mem

モードを mem にします。 rtcwake のモードと ACPI の6段階( S0 から S5 )との対応関係は次のようになっています。( )内が rtcwake-m 指定語です。

ACPI 内容 rtcwake
S0 通常の稼働状態 on
S1 スタンバイで通電したまま動作を停止 standby
S2 スタンバイとスリープの中間状態 freeze ?
S3 RAM以外の電源を落とすスリープ mem
S4 メモリの内容をDiSKに退避して電源を切る disk
S5 完全な電源オフ(シャットダウン) off

一般にS0からS5に向かって節電の程度が大きくなります。

省エネ的にはモードをoffにして( -m off ) 完全にシャットダウンしておくのが一番ですが、PCによっては自動復帰しないことがあるようです(事例)。

わが家の X230 は、最初のテストでは動いていたのですが、1週間ほど試験運転をやっていたら、ときどき復帰しないことがありました。

そこで 節電効果の大きい順(disk > mem > freeze…)に自動復帰テストをしてみました。そうすると disk でも自動復帰しない現象が発生しましたので、現在は mem で運用しています。 mem はいまのところ正常に動いています。 -m mem でも節電率は90%ほどになりますし、復帰の スピード が速いので、まぁ良しとしています。

rtcwake による自動復帰の日時指定方法

-t "$(date +\%s -d 'tomorrow 21:00')"

このようにUnixの date コマンドのフォーマットで自動復帰の日時を指定します。 +%s のパーセント記号を +\%s とエスケープすることを忘れずに。

なお --date 21:00 のような指定も可能です。マニュアルにはよれば次のような使い方ができると書いてあります。

YYYYMMDDhhmmss
YYYY-MM-DD hh:mm:ss
YYYY-MM-DD hh:mm    秒=00 に設定
YYY-MM-DD           時刻=00:00:00 に設定
hh:mm:ss            日付=今日 に設定
hh:mm               日付=今日、秒=00 に設定
tomorrow            時刻=00:00:00 に設定

rtcwakeの状態確認やデバッグ

rtcwake の状態を確認したり、停止したりする方法は次のとおりです。

(rtcwakeの状態を表示する)
$ sudo rtcwake -m show

(rtcwakeを停止する)
$ sudo rtcwake -m disable

rtcwake の動作確認やデバッグの際には、 -m no とすれば、 rtcwake コマンド実行時に電源はオフにならず、PCはそのまま起動中になります。必要な作業が終わった後で手動で電源をオフにしても、 rtcwake で予約設定した自動復帰の時刻になれば、ちゃんとPCは復帰します。

祝日の取り扱い

上述したように、土日に株価取得スクリプトを起動させないようにするために crontab で週日を 1-5 指定しました。

祝日には株価取得しない

あとの問題は 曜日は平日なのに休業になる 祝日 の取扱い。

スクリプトは曜日が平日にも起動してきますので、「祝日」の判定は株価取得スクリプトの 内部 で行います。

スクリプト内の祝日判定方法

内閣府のHPから「祝日データ」をPCにダウンロードします。データは1995年1月以降 2022年末までの祝日が次のようなCSVファイルになっています3

 :
2022/9/23,秋分の日
2022/10/10,スポーツの日
2022/11/3,文化の日
2022/11/23,勤労感謝の日

これを holidays.csv とかのファイルに保存しておきます。

祝日かどうかの判定は、シンプルに grep を使って「当日の日付が祝日ファイルの中にあるかどうか」を見て行います。

日付フォーマットに注意

ちょっと気をつけなければならないのは、内閣府のCSVデータでは、月日のデータは次のようにリーディングゼロの無い形式になっていること:

(例)2021/5/4,みどりの日

したがって

  1. 祝日ファイルの日付フォーマットを次のようにして 2021/05/04 の形式に変換するか

    awk -F"," '{print $1}' holidays.csv | date -f - '+%Y/%m/%d'
    
  2. 判定の時に使う「今日の日付」のフォーマットを date '%Y/%-m/%-d' にして使うか

どちらかになります。

年末年始の休業日など

内閣府のデータに掲載されていない祝日や休業日は、手動で次のように holidays.dat ファイル内に書き加えておきます。

2021/12/31,年末年始休業
2022/1/1,年末年始休業
2022/1/2,年末年始休業
2022/1/3,年末年始休業

rtcwake+cron の問題点など

-m off の不安定さ

rtcwake のマニュアルには -m off も「たいていの場合には動く」とあります。しかし安定的に自動復帰するかどうかは、PCごとにテストしてみることが必要です。

-m mem にすれば、おおかたのPCで問題なく自動復帰すると思います。

-m mem でも・・・(2021/12/23追記)

-m mem でスリープ状態の時に一度でもフタを開くとシステムが復帰します4。そのときの rtcwake の状態を見ると:

% sudo rtcwake -m show
アラーム: off

つまり、フタを空ける前にセットされていた自動復帰の設定は disable になります。

自動復帰の設定をしたPCを いじった ときには、必ず rtcwake -m show して状態を確認した方が良いでしょう。

rtcwake メッセージの分かりにくさ

-m show した例をあげます:

$ sudo rtcwake -m show
rtcwake: RTC が UTC を使用しているものと仮定します ...
アラーム: ON  Sat Dec 18 02:59:00 2021

問題は、2行目。

これを見て、最初はディフォールトではローカル時間(JST)を使ってくれるはずなのに、なんで勝手に「UTCを使用しているものと仮定」するの? 3行目のアラーム時刻はUTCになってるし・・。もしかしたら自分の設定がまずかったかも知れないと焦りました。けど、英語のメッセージをみると:

rtcwake: assuming RTC uses UTC …

ですので、あぁ「仮定すると・・・」なんだね、とほっとしました 😓

cronではまる

cronで動かすことを想定して作っていないプログラムやスクリプトは、ときどき(というかしばしば 😓 )単独ではちゃんと動くのにcronでは動かないことが起こります。

これについても、たくさんの良い説明記事がネット上にありますので、そちらを見てください。
(完)


補足説明1(ノートPCのフタを閉じてもスリープしない設定)

フタを閉じてもパソコンをスリープさせない方法はつぎのとおりです。

1) 設定ファイルの編集

/etc/systemd/logind.conf の次の行を編集します:

<デフォルト>
HandleLidSwitch=suspend
<変更後>
HandleLidSwitch=ignore

2) サービスを再起動

# systemctl restart systemd-logind.service

これだけです。

Footnotes:


  1. わが国では、ネットから自動的に株価や価額、為替レートなどのデータを取得するスクレーピングは多くのサイトで禁止されています。最近になって一部それを許容するサイトがわが国にも出始めていますが、いまのところ外国の公開サイトなどからのデータ取得に頼らざるを得ません。 ↩︎

  2. X230の発表年、出荷開始年は2013年です。 ↩︎

  3. 2021年12月中旬の時点 ↩︎

  4. この挙動はPCによって違う可能性があります。X230の場合には、スリープ状態のときにはフタにあるステータス インジケータの三日月マーク(下図の[1])が緑に点灯します。この時にフタを開けるとシステムが復帰するのがデフォルトです。

     ↩︎