基于 iOS Sysdiagnose 的耗电自动化测试
目录
一、基本概念
1.1 电量单位
- 电量(Q):用 Q 表示,单位是库仑(C)
- 电流(I):用 I 表示,单位是安培(A)
- 时间(t):用 t 表示,单位是秒(s)
- 关系式:Q = I × t
- 单位换算:1A = 1000mA
1.2 电池容量
- mAh(毫安时):手机电池容量常用单位
- 含义:1000mAh 的电池容量,表示在电流 1000mA 的情况下,可以持续放电 1 小时
- mAh 和库仑的关系:
1mAh = 3.6 库仑
1000mAh = 1000mA × 1h = 1000mA × 3600s = 1A × 3600s = 3600 库仑
1.3 能耗单位
- mWh(毫瓦时):能耗单位
- mWh 和 mAh 的关系:
mWh = mAh × U(电压) - 能量计算公式:
能量 E = 功率 P × 时间 t
功率 P = 电压 U × 电流 I
因此:mWh = U × I × t = U × mAh
二、测试结果
2.1 测试前置条件
- 手机型号:iPhone 6S
- 出厂电池容量:1715mAh
- 测试应用:腾讯会议
- Bundle ID:
com.tencent.meeting.db.haven - 测试时间:1 小时(独占模式)
- 测试时间段:2021-1-13 16:00 ~ 17:00
2.2 1 小时测试结果
2.2.1 整机耗电量
- 统计时长:3604s
- 整机耗电量:574mAh(精准值)
2.2.2 基于能耗计算的耗电量
- 平均电压:3.885V
- 模块总能耗:2175679mWh
- 计算得到总耗电量:mAh = 2175679 / 3885 = 560mAh
2.2.3 应用耗电量
- 平均电压:3.885V
- 腾讯会议各模块总能耗:2050807mWh
- 计算得到腾讯会议总耗电量:mAh = 2050807 / 3885 = 528mAh
2.2.4 数据差异说明
- 560mAh 和 574mAh 的差距:主要是由于电压存在波动,而计算采用的是平均电压值
- 应用耗电量小于模块总耗电量:在独占模式下,App 的总耗电量(528mAh)小于模块的总耗电量(560mAh),是由于系统存在其他后台进程
三、iOS Sysdiagnose 的使用方法
3.1 开启系统诊断
- 下载 Profile(有效期 7 天),并安装到 iOS 设备(可以使用 AirDrop 传递到电脑)
- 信任 Profile:
- 打开 iPhone 系统设置 → 通用 → 描述文件
- 选择信任 System Debug Profile
- 同步设备信息到电脑:这个同步操作用于保存历史数据
- 开始测试:
- 复现问题或开始测试
- 记录问题出现的日期或时间
- 再次同步信息到电脑:测试完成后再次同步
⚠️ 注意事项:重启手机会导致 Profile 文件失效
3.2 关闭系统诊断
- 打开 iPhone 系统设置 → 通用 → 描述文件
- 选择移除 System Debug Profile
- 重启手机
3.3 诊断日志存储位置
电池诊断日志文件名以 Powerlog_ 开头,并以 .PLSQL 或 .PLSQL.gz 结尾。
macOS
~/Library/Logs/CrashReporter/MobileDevice/[Your_Device_Name]/
iOS
Settings.app > Privacy > Analytics > Analytics Data
Windows 10
%appdata%\..\Local\Packages\AppleInc.iTunes_devicename\LocalCache\Roaming\AppleComputer\Logs\CrashReporter\MobileDevice\[Your_Device_Name]/DiagnosticLogs/
3.4 同步设备信息(iPhone → Mac)
打开 Finder → 左侧找到对应的设备 → 点击右下角的同步按钮

四、电池诊断日志分析
电池诊断日志使用数据库进行存储,数据库包含多张表,表数量与 iOS 系统版本相关。例如,iOS 14 系统有 450 张表。
4.1 整机电量表
表名:PLBatteryAgent_EventBackward_Battery
以 20s 的采样频率记录本机的电量、温度、电压、电流等信息,少数样本不受 20s 采样频率限制。
4.1.1 查询示例
SELECT
datetime(timestamp, 'unixepoch', 'localtime') AS time,
Level,
RawLevel,
AbsoluteLevel,
MaxCapacity,
AbsoluteCapacity,
DesignCapacity,
AppleRawMaxCapacity,
AppleRawCurrentCapacity
FROM PLBatteryAgent_EventBackward_Battery
WHERE timestamp > 1610503788.63826

4.1.2 字段解释
重要字段:
- DesignCapacity:电池出厂容量
- iPhone 6S 容量是 1715mAh,查询结果 1690mAh,基本一致
- AbsoluteCapacity:电池当前容量
其他字段:
- Level:手机显示的电量剩余百分比
- RawLevel:剩余时间电量百分比
- MaxCapacity:电池最大容量百分比,固定值 100
- CurrentCapacity:同 Level,看起来是整型
- Voltage:电池当前电压值,存在小幅度的波动
计算字段:
- 已消耗电量 = AppleRawMaxCapacity – AppleRawCurrentCapacity
- 电池的实际容量 = AppleRawMaxCapacity – AppleRawCurrentCapacity + AbsoluteCapacity
示例:电池的实际容量计算出来固定为 1380mAh,也就是说 iPhone 6S 的出厂电量为 1690mAh,电池衰退之后目前为 1380mAh

4.1.3 一小时整机的电量消耗
查询结果:3604.26s 时间内,手机耗电量 574mAh
SELECT
t1.start_ts,
t1.start_cap,
t1.start_time,
t2.end_cap,
t2.end_ts,
t2.end_time,
(t2.end_ts - t1.start_ts) AS delta_ts,
(t1.start_cap - t2.end_cap) AS delta_cap
FROM
(
SELECT
datetime(timestamp, 'unixepoch', 'localtime') AS start_time,
timestamp AS start_ts,
AbsoluteCapacity AS start_cap
FROM PLBatteryAgent_EventBackward_Battery
WHERE timestamp >= 1610524800 AND IsCharging = 0
ORDER BY start_time
LIMIT 1
) t1,
(
SELECT
datetime(timestamp, 'unixepoch', 'localtime') AS end_time,
timestamp AS end_ts,
AbsoluteCapacity AS end_cap
FROM PLBatteryAgent_EventBackward_Battery
WHERE timestamp >= 1610524800 + 3600 AND IsCharging = 0
ORDER BY end_time
LIMIT 1
) t2

4.2 节点关系表
表名:PLAccountingOperator_EventNone_Nodes
硬件模块和 APP 在其他表的信息统计统一使用的 NodeId,通过这个表可以知道具体 NodeId 对应的硬件模块或者 APP。
4.2.1 查询示例
SELECT * FROM PLAccountingOperator_EventNone_Nodes;

4.2.2 字段解释
- IsPermanent:Node ID 是否固定不变
- 硬件模块的 Node ID 是固定不变的
- APP 的 Node ID 可能发生变化(比如 APP 卸载重装)
4.3 节点耗电详情表
表名:PLAccountingOperator_Aggregate_RootNodeEnergy
耗电详情表按小时统计数据,统计数据写入数据库表有一个小时的延迟。
示例:统计 9~10 点的耗电详情,可能要等到 11 点才能拿到完整的统计数据
4.3.1 字段解释
- Energy:能耗,单位 mWh,mWh = mAh × 电压
4.3.2 一小时整机能耗详情
查询结果:总能耗为 2175679.927882,16:00~17:00 平均电压为 3.885V
mAh = 2175679 / 3885 = 560mAh
这个数值和 2.2.1 例子中的 574mAh 基本一致。
查询总能耗:
-- 查询总能耗
SELECT
datetime(timestamp, 'unixepoch', 'localtime') AS time,
timestamp,
sum(Energy) AS total_energy
FROM PLAccountingOperator_Aggregate_RootNodeEnergy
WHERE timestamp = 1610525013.0
ORDER BY time
查询各个模块的能耗:
-- 查询各个模块的能耗
SELECT
datetime(timestamp, 'unixepoch', 'localtime') AS time,
timestamp,
sum(Energy) AS total_energy,
RootNodeID,
(SELECT Name FROM PLAccountingOperator_EventNone_Nodes WHERE ID = PLAccountingOperator_Aggregate_RootNodeEnergy.RootNodeID) AS RootNodeName
FROM PLAccountingOperator_Aggregate_RootNodeEnergy
WHERE timestamp >= 1610525013.0
GROUP BY RootNodeID, timestamp
ORDER BY time

4.3.3 一小时应用能耗详情
查询结果:总能耗为 2050807,16:00~17:00 平均电压为 3.885V
mAh = 2050807 / 3885 = 528mAh
APP 总能耗:
-- APP 总能耗
SELECT
datetime(timestamp, 'unixepoch', 'localtime') AS time,
timestamp,
sum(Energy),
NodeID,
(SELECT Name FROM PLAccountingOperator_EventNone_Nodes WHERE ID = PLAccountingOperator_Aggregate_RootNodeEnergy.NodeID) AS NodeName
FROM PLAccountingOperator_Aggregate_RootNodeEnergy
WHERE NodeID = (SELECT ID FROM PLAccountingOperator_EventNone_Nodes WHERE Name = 'com.tencent.meeting.db.haven')
AND timestamp = 1610525013.0
ORDER BY time
APP 各模块能耗:
-- APP 各模块能耗
SELECT
datetime(timestamp, 'unixepoch', 'localtime') AS time,
timestamp,
ID,
timeInterval,
Energy,
NodeID,
(SELECT Name FROM PLAccountingOperator_EventNone_Nodes WHERE ID = PLAccountingOperator_Aggregate_RootNodeEnergy.NodeID) AS NodeName,
RootNodeID,
(SELECT Name FROM PLAccountingOperator_EventNone_Nodes WHERE ID = PLAccountingOperator_Aggregate_RootNodeEnergy.RootNodeID) AS RootNodeName
FROM PLAccountingOperator_Aggregate_RootNodeEnergy
WHERE NodeID = (SELECT ID FROM PLAccountingOperator_EventNone_Nodes WHERE Name = 'com.tencent.meeting.db.haven')
AND timestamp = 1610525013.0
ORDER BY time

五、电量自动化测试
电量自动化需要借助一个 USB 控制电路板,用于控制手机充断电。电源线无法直连 Mac 的原因是因为 USB 控制面板只有 Windows 版本。
连接示意图和流程如下:

六、电量日志自动解析
6.1 目标
- 自动分析应用能耗和变化趋势:
- 每次测试整机的能耗变化趋势
-
应用能耗的变化趋势
-
能耗变化自动输出:
- 当应用能耗发生变化时,能够自动输出应用能耗分布详情
- 能够直观地看到变化的部分
6.2 分析视图

6.2.1 系统电量百分比
观察手机电量的变化趋势,每次电量测试的时候,手机都是断电状态。
- 断电:对应下行曲线
- 充电:对应上行曲线
由
PLBatteryAgent_EventBackward_Battery原始数据得到绘制曲线
6.2.2 系统每小时电量
系统电量百分比只能看到系统的电量变化趋势,并不能直观地看到系统每小时的耗电量,这也是系统每小时电量视图存在的原因。
它是由
PLBatteryAgent_EventBackward_Battery原始表数据,计算每个整点的电量差值而得到绘制曲线
6.2.3 应用每小时能耗
存在实际能耗和每小时能耗两条曲线的原因:
- 当应用的测试时间不足一个小时时,实际能耗要转换为每小时能耗,这样才方便能耗的对比
- 建议:每次测试时间都是从整点开始跑满一个小时
6.2.4 应用每小时耗电量
应用每小时耗电量是根据应用的能耗和电压计算而来的,目的主要是为了方便得出应用的具体耗电量,这样也方便和整机的耗电量进行对比。
注意:由于电压取的是一个小时的平均值,所以应用每小时计算出的耗电量和实际的耗电量可能存在小量误差
七、常见问题
7.1 电量日志时间戳无法更新
问题:有些手机在获取电量日志的时候,可能存在电量日志时间戳无法更新的情况
解决方法:目前知道的解决方法是还原系统
7.2 为什么存在实际能耗和每小时能耗
主要是由于测试时间可能不足一个小时,统一换算成每小时能耗,方便对比。
八、电量分析方法对比
| 方法名 | 优点 | 缺点 | 方法改进 |
|---|---|---|---|
| 人眼计时法 | 简单,不需要辅助工具 |
|
|
| Instruments 提供的能量日志方法 |
|
|
– |
| 苹果系统诊断方法 | 提供系统、应用、模块的电量详情 |
|
挑选出几张核心的数据表 |
8.1 自动化改进
即使有苹果提供的系统电量诊断方法,进行电量测试依然需要人工介入,费时费力,主要表现在:
- 每次测试前需要充电
- 测试过程中需要断电
- 只能整点开始测试
- 测试结束之后需要等待 2、3 个小时之后才能拿到测试数据
- 测试数据需要从 iPhone 手工同步到电脑上进行分析
一轮测试下来基本需要耗费几个小时
8.2 计算方法说明
通过能耗和电压去计算系统的整机耗电量,和应用的耗电量。
九、电量优化建议
9.1 平台优化建议
| 平台 | 优化建议 |
|---|---|
| mac |
|
| Windows |
|
| Android |
|
| iOS | 待补充 |
9.2 iOS 平台优化建议
注意:iOS 平台的优化建议需要根据实际测试结果和性能分析进行补充
