-
-
Save ithinkihaveacat/7e7d0f2f620cc27ad606d2df85d81fa5 to your computer and use it in GitHub Desktop.
Simple parser for `adb shell dumpsys batterystats` output
This file contains hidden or 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
#!/usr/bin/env node | |
// usage: | |
// | |
// $ adb shell dumpsys batterystats | ./process.js | |
// 1706369159690,2024-01-27 15:25:59,86 | |
// 1706372879649,2024-01-27 16:27:59,85 | |
// 1706378519690,2024-01-27 18:01:59,84 | |
// 1706381668555,2024-01-27 18:54:28,82 | |
// 1706386019511,2024-01-27 20:06:59,81 | |
// [ ... ] | |
const fs = require("fs"); | |
const readline = require("readline"); | |
const BATTERY_HISTORY_ENTRY_REGEX = new RegExp( | |
"^\\s*(?:(?:\\+(?:(\\d+)d)?(?:(\\d+)h)?(?:(\\d+)m)?" + | |
"(?:(\\d+)s)?(?:(\\d+)ms)?)|0) \\(\\d+\\) (.+)$" | |
); | |
const TIME_MESSAGE_REGEX = | |
/^(?:RESET:)?TIME: (\d{4})-(\d{2})-(\d{2})-(\d{2})-(\d{2})-(\d{2})$/; | |
const BATTERY_PERCENT_REGEX = /^\s*(\d{3})/; | |
function timeOffsetFromHistoryEntryMatch(result) { | |
// Parse the components of the relative timestamp | |
const [d, h, m, s, ms] = result | |
.slice(1, 6) | |
.map((v) => (v ? Number(v) || 0 : 0)); | |
return ms + 1000 * (s + 60 * (m + 60 * (h + d * 24))); | |
} | |
function utcTimestampFromTimeMessageMatch(timeResult) { | |
return Date.UTC( | |
Number(timeResult[1]), | |
Number(timeResult[2]) - 1, | |
Number(timeResult[3]), | |
Number(timeResult[4]), | |
Number(timeResult[5]), | |
Number(timeResult[6]), | |
0 | |
); | |
} | |
function utcTimestampToTimeString(t) { | |
const date = new Date(t); // Convert to milliseconds | |
const year = date.getFullYear(); | |
const month = String(date.getMonth() + 1).padStart(2, "0"); // Month starts from 0 | |
const day = String(date.getDate()).padStart(2, "0"); | |
const hours = String(date.getHours()).padStart(2, "0"); | |
const minutes = String(date.getMinutes()).padStart(2, "0"); | |
const seconds = String(date.getSeconds()).padStart(2, "0"); | |
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; | |
} | |
let inputSource; | |
// Check if a file name is passed | |
if (process.argv.length >= 3) { | |
const filePath = process.argv[2]; | |
// Create a readable stream | |
inputSource = fs.createReadStream(filePath); | |
// Handle file not found error | |
inputSource.on("error", (err) => { | |
console.error(`Could not open file: ${err.message}`); | |
process.exit(1); | |
}); | |
} else { | |
// If no file name is provided, read from stdin | |
inputSource = process.stdin; | |
} | |
const rl = readline.createInterface({ | |
input: inputSource, | |
output: process.stdout, | |
terminal: false, | |
}); | |
let lastExplicitUtcTimestamp; | |
let lastExplicitOffset; | |
let lastPercent; | |
rl.on("line", (line) => { | |
if (line.match(/^Per-PID Stats/)) { | |
process.exit(0); | |
} | |
const result = line.match(BATTERY_HISTORY_ENTRY_REGEX); | |
let utcTimestamp = null; | |
if (result) { | |
const offset = timeOffsetFromHistoryEntryMatch(result); | |
message = result[6]; | |
// Check if the message contains an absolute timestamp | |
const timeResult = message.match(TIME_MESSAGE_REGEX); | |
if (timeResult) { | |
utcTimestamp = utcTimestampFromTimeMessageMatch(timeResult); | |
lastExplicitUtcTimestamp = utcTimestamp; | |
lastExplicitOffset = offset; | |
} else if (lastExplicitUtcTimestamp) { | |
utcTimestamp = lastExplicitUtcTimestamp - lastExplicitOffset + offset; | |
} | |
} else { | |
// continuation of the previous line, reuse the previous timestamp | |
message = line; | |
} | |
let percent; | |
const resultMessage = message.match(BATTERY_PERCENT_REGEX); | |
if (resultMessage) { | |
percent = parseInt(resultMessage[0], 10); | |
} else { | |
return; | |
} | |
if (lastPercent == percent) { | |
return; | |
} else { | |
lastPercent = percent; | |
} | |
if (utcTimestamp && percent) { | |
//console.log({ utcTimestamp, timestamp, percent, message, line }); | |
console.log( | |
[utcTimestamp, utcTimestampToTimeString(utcTimestamp), percent].join(",") | |
); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment