ここでは ノートPCを定時にオン・オフする方法、つまり:
毎日一定の時刻にPCを立ち上げ
特定のプログラムを走らせ
終わったら電源をオフにする
方法を 自分向けの備忘をかねて紹介します。
ここで「特定のプログラム」のイメージとしては
- 為替レートや株価などを自動取得1するとか、銀行から入出金明細書のCSVファイルをダウンロードするなどの 会計・経理的 なプログラム
- 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の電源をオン・オフし、プログラムを起動するケースを例にとって説明します。
時刻 | 電源状態 | 備考 |
---|---|---|
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,みどりの日
したがって
-
祝日ファイルの日付フォーマットを次のようにして
2021/05/04
の形式に変換するかawk -F"," '{print $1}' holidays.csv | date -f - '+%Y/%m/%d'
-
判定の時に使う「今日の日付」のフォーマットを
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
これだけです。