Extract just one data point from powermetrics, suitable for graphing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!python -u | |
import subprocess | |
import plistlib | |
import sys | |
""" | |
Print selected power metrics from /usr/bin/powermetrics at intervals, suitable | |
for graphing. | |
""" | |
# available data is determined by which categories we ask for (the -s option) | |
interval = sys.argv[1] if len(sys.argv) > 1 else 1000 | |
cmd = f"sudo powermetrics -i {interval} -s cpu_power --format plist" | |
# Execute the long-running command, which produces one plist to stdout every | |
# interval, spread across multiple lines. | |
# For each line of output from `powermetrics`: | |
# - accumulate lines into a bytearray | |
# When "</plist>" is seen: | |
# - parse the accumulated bytearray into a plist | |
# - print the combined power consumption | |
# - clear the bytearray | |
pl = bytearray() | |
# using shell mode here because we need sudo for powermetrics | |
for line in subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).stdout: | |
pl.extend(line) | |
# look for the plist close tag | |
if "</plist>" in str(line): | |
# powermetrics adds a null byte at the start of each plist after the | |
# first, which breaks the plist parser. Remove it. | |
if pl[0] == 0: | |
pl = pl[1:] | |
d = plistlib.loads(pl[0:]) | |
print(d.get('processor').get('combined_power')) | |
#print(d.get('all_tasks').get('cputime_ms_per_s')) # requires "all_tasks" category | |
pl = bytearray() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment