バッテリーの状況
Windows でバッテリーの状況は Win32API の関数を使うと取れる。しかし pywin32 *1 には肝心の GetSystemPowerStatus 関数 *2 がないじゃないか。
しょうがないので伝家の宝刀 ctypes *3 を使うべ。GetSystemPowerStatus 関数自体はそう難しくない。所定の構造体へのポインターを渡すと、バッテリーの情報を入れてくれる、というよくあるパターンだ。これならC初心者の自分にもできるはずだ。
まずは import
import ctypes from ctypes import wintypes
wintypes には BYTE や DWORD などの型が定義されている。どのように typedef されているのかわざわざ調べなくても済む。
次に、SYSTEM_POWER_STATUS 構造体を作ろう。http://msdn.microsoft.com/en-us/library/aa373232%28VS.85%29.aspx を見てどのようなメンバーがあるかのか調べて並べる。
class SYSTEM_POWER_STATUS(ctypes.Structure): _fields_ = [("ACLineStatus", wintypes.BYTE), ("BatteryFlag", wintypes.BYTE), ("BatteryLifePercent", wintypes.BYTE), ("Reserved1", wintypes.BYTE), ("BatteryLifeTime", wintypes.DWORD), ("BatteryFullLifeTime", wintypes.DWORD), ] stat = SYSTEM_POWER_STATUS() # さっそく1個作る
O.K.
次に GetSystemPowerStatus 関数の詳細を調べる。http://msdn.microsoft.com/en-us/library/aa372693%28VS.85%29.aspx
ページの終わりにある requirements を見よう。場所は Kernel32.dll だから ctypes.windll.kernel32.GetSystemPowerStatus で関数が呼び出せる。
戻り値が BOOL であることを知せるために、
ctypes.windll.kernel32.GetSystemPowerStatus.restype = wintypes.BOOL
とやる。
最後に、引数はポインタ渡しだから、
nerr = ctypes.windll.kernel32.GetSystemPowerStatus(ctypes.byref(stat))
のように呼べばいい。
完成図はこうだ。
#! c:\Python25\python.exe # -*- coding: cp932 -*- import ctypes from ctypes import wintypes class SYSTEM_POWER_STATUS(ctypes.Structure): _fields_ = [("ACLineStatus", wintypes.BYTE), ("BatteryFlag", wintypes.BYTE), ("BatteryLifePercent", wintypes.BYTE), ("Reserved1", wintypes.BYTE), ("BatteryLifeTime", wintypes.DWORD), ("BatteryFullLifeTime", wintypes.DWORD), ] stat = SYSTEM_POWER_STATUS() ctypes.windll.kernel32.GetSystemPowerStatus.restype = wintypes.BOOL nerr = ctypes.windll.kernel32.GetSystemPowerStatus(ctypes.byref(stat)) if not nerr: import sys sys.exit('情報が取得できません。') if stat.ACLineStatus == 0: print '電源に接続していません。' elif stat.ACLineStatus == 1: print '電源に接続しています。' elif stat.ACLineStatus == 255: print '電源の状態が不明です。' if stat.BatteryLifePercent == 255: print '残量不明' else: print "残量 %d%%" % stat.BatteryLifePercent