ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Python - 指定した時間にPCを強制的にスリープさせる

初めに

 今回はプログラムからPCをスリープ状態にする方法を学ぶために、指定した時間にPCを強制スリープさせるコードを書いてみます。PCをだらだらと使ってしまう方にはおすすめです。

目標

 次の機能をもつ関数を定義する。

  • 時間を指定し、その時間に強制的にPCをスリープ状態にする
  • すでに過ぎている時間を入力した場合は、そのことを表示する

コード全文

import time
import os
from datetime import datetime

def sleep_at_specific_time(target_hour, target_minute):
    # 現在時刻の取得
    today = datetime.now()

    # 指定した時刻を引数からdatetime.timeに変換
    target_time = datetime(today.year, today.month, today.day, target_hour, target_minute).time()

    # 指定の時間までの秒数を算出
    time_diff = (datetime.combine(today, target_time) - today).total_seconds()

    if time_diff > 0:
        time.sleep(time_diff) # 指定した時間まで待機

        # 指定した時間になったらPCをスリープさせる
        os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")
    else:
        print("時間を過ぎてます\n現在時刻:" + today.strftime('%Y/%m/%d %H:%M'))


# 第1引数には何時、第2引数に何分を記入
# 例:sleep_at_specific_time(23, 40), 23時40分にsleep
sleep_at_specific_time(20, 20)

解説

os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")

 os.system モジュールを使用して、Windowsrundll32.exe を呼び出しています。

 dll(Dynamic Link Library)とは、複数のアプリケーションソフトに共通している部分をOSにファイルとして保存し、アプリケーションソフトを実行する際に、それを呼び出して利用する方法、また、そのプログラムを言います。

 rundll32.exe は dll の中にある関数を呼び出すときに使う実行ファイルです。次の形式で入力することで、dllファイル内の関数を呼び出せます。

rundll32.exe 【DLLファイルの名前】, 【関数の名前】 【関数に渡す値】

 os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")powrprof.dll 内の SetSuspendState 関数に 0, 1, 0という引数を渡し、呼び出しています。

 SetSuspendState 関数はシステムを中断(スリープ)状態または休止状態(S4)にするための関数です。

BOOLEAN SetSuspendState(
  [in] BOOLEAN bHibernate,
  [in] BOOLEAN bForce,
  [in] BOOLEAN bWakeupEventsDisabled
);
  • bHibernate:Trueの場合は休止状態、Falseの場合は中断状態にする
  • bForce:何も作用しない
  • bWakeupEventsDisabled:Trueの場合はすべてのウェイクイベントを無効、Falseの場合はすべてのウェイクイベントを有効にする

 今回は、0, 1, 0 であったので、中断(スリープ)状態でウェイクイベントは有効にしています。

問題点

  • 日付をまたぐことができない

 今回は日付をまたぐ必要性を感じなかったので、あえてこのような設計にしました。datetimeで作成しているため、年月日を含めて引数として入力させるようにすれば解消はできます。
 また、何分後のような指定の仕方に変更することも可能です。