如何检查屏幕是否由于 Mac/Python 下系统偏好设置中的节能设置而关闭?
2 回答
快速而肮脏的解决方案:调用ioreg
并解析输出。
import subprocess
import re
POWER_MGMT_RE = re.compile(r'IOPowerManagement.*{(.*)}')
def display_status():
output = subprocess.check_output(
'ioreg -w 0 -c IODisplayWrangler -r IODisplayWrangler'.split())
status = POWER_MGMT_RE.search(output).group(1)
return dict((k[1:-1], v) for (k, v) in (x.split('=') for x in
status.split(',')))
在我的电脑中, 的值CurrentPowerState
是4
屏幕打开和1
屏幕关闭的时间。
更好的解决方案:用于ctypes
直接从IOKit
.
我能想到的唯一方法是使用OSX pmset 电源管理 CML 工具
描述
pmset changes and reads power management settings such as idle sleep timing, wake on administrative access, automatic restart on power loss, etc.
请参阅以下链接,它将提供大量信息,可以帮助您准确完成您正在寻找的内容。
http://managingamac.blogspot.com/2012/12/power-assertions-in-python.html
我将包含链接提供的代码以用于“保存和记录”目的:
#!/usr/bin/python
import ctypes
import CoreFoundation
import objc
import subprocess
import time
def SetUpIOFramework():
# load the IOKit library
framework = ctypes.cdll.LoadLibrary(
'/System/Library/Frameworks/IOKit.framework/IOKit')
# declare parameters as described in IOPMLib.h
framework.IOPMAssertionCreateWithName.argtypes = [
ctypes.c_void_p, # CFStringRef
ctypes.c_uint32, # IOPMAssertionLevel
ctypes.c_void_p, # CFStringRef
ctypes.POINTER(ctypes.c_uint32)] # IOPMAssertionID
framework.IOPMAssertionRelease.argtypes = [
ctypes.c_uint32] # IOPMAssertionID
return framework
def StringToCFString(string):
# we'll need to convert our strings before use
return objc.pyobjc_id(
CoreFoundation.CFStringCreateWithCString(
None, string,
CoreFoundation.kCFStringEncodingASCII).nsstring())
def AssertionCreateWithName(framework, a_type,
a_level, a_reason):
# this method will create an assertion using the IOKit library
# several parameters
a_id = ctypes.c_uint32(0)
a_type = StringToCFString(a_type)
a_reason = StringToCFString(a_reason)
a_error = framework.IOPMAssertionCreateWithName(
a_type, a_level, a_reason, ctypes.byref(a_id))
# we get back a 0 or stderr, along with a unique c_uint
# representing the assertion ID so we can release it later
return a_error, a_id
def AssertionRelease(framework, assertion_id):
# releasing the assertion is easy, and also returns a 0 on
# success, or stderr otherwise
return framework.IOPMAssertionRelease(assertion_id)
def main():
# let's create a no idle assertion for 30 seconds
no_idle = 'NoIdleSleepAssertion'
reason = 'Test of Pythonic power assertions'
# first, we'll need the IOKit framework
framework = SetUpIOFramework()
# next, create the assertion and save the ID!
ret, a_id = AssertionCreateWithName(framework, no_idle, 255, reason)
print '\n\nCreating power assertion: status %s, id %s\n\n' % (ret, a_id)
# subprocess a call to pmset to verify the assertion worked
subprocess.call(['pmset', '-g', 'assertions'])
time.sleep(5)
# finally, release the assertion of the ID we saved earlier
AssertionRelease(framework, a_id)
print '\n\nReleasing power assertion: id %s\n\n' % a_id
# verify the assertion has been removed
subprocess.call(['pmset', '-g', 'assertions'])
if __name__ == '__main__':
main()
http://opensource.apple.com/source/PowerManagement/PowerManagement-211/pmset/pmset.c
该代码依赖于 IOPMLib,它的功能是做出断言、安排电源事件、测量热量等等。
https://developer.apple.com/library/mac/#documentation/IOKit/Reference/IOPMLib_header_reference/
要通过 Python 调用这些函数,我们必须通过 IOKit 框架。
http://developer.apple.com/library/mac/#documentation/devicedrivers/conceptual/IOKitFundamentals/
为了让我们在 Python 中操作 C 数据类型,我们将使用一个名为 ctypes 的外部函数接口。
http://python.net/crew/teller/ctypes/
这是作者在页面上描述的包装器;由迈克尔林恩撰写。我从上面的作者链接中发布的代码是对该代码的重写,以使其更易于理解。