【问题标题】:Detailed battery usage - iOS详细的电池使用情况 - iOS
【发布时间】:2014-09-09 23:50:54
【问题描述】:

我当前的项目是一个持续存在的应用程序(想想 Tinder 或 Foursquare),而且电池消耗非常大。我们认为主要的电力消耗是 GPS 和 WiFi 天线。我们希望能够测量我们的应用在几种不同配置下的能源使用情况。

但是如何做到这一点呢?我们想要一个流程:

  • 可以在手机与计算机断开连接的情况下使用(因此我们知道我们使用的是电池而不是通过 USB 供电),
  • 具有足够的粒度,使我们能够将能量峰值与应用程序事件(启动应用程序、更新位置、将分析信息发送到 Mixpanel 等)相关联,
  • 可以在没有保姆的情况下通宵运行,
  • 可以导出为 CSV 或其他用于统计分析的文件。

清单,我知道。

这些是要求,以下是我知道的选项:

1.在 iOS 设备上打开不受限制的能量诊断记录,并导出到仪器

这是显而易见的答案,但它有一个巨大的缺陷。

优点:

  • 使用电池代替 USB 电源。
  • 出色的粒度(1 秒时间序列数据,20 个离散能源使用水平),
  • 与 GPS 天线使用等其他设备事件相关。

缺点:

2。通过 Instruments 监控插入的手机

优点:

  • 与其他设备事件具有同样出色的粒度和相关性。
  • 电池不能用完。

缺点:

  • 不使用电池,因此能耗无法与实际使用情况相比。
  • 仪器甚至不能可靠地显示能源使用情况。有时它只是空白。
  • 无法导出为 CSV。

3.在我们的应用中使用公共 Cocoa API 记录能源使用情况 - [UIDevice.currentDevice batteryLevel]

这是关于 SO 的最常见答案。我看过Estimated battery time on iOSiphone: Calculating battery life 和其他十几个。

优点:

  • 测量之间的任意小时间。
  • 可以通过以某种方式(CoreData、默认值、网络等)写入磁盘而在电池耗尽的情况下保留数据。
  • 可以为数据选择任意格式,例如 CSV。

缺点:

  • 比其他方法多得多的工作。
  • 公共 API 只能为您提供 5% 的电池电量准确度。这实质上是我们从方法 1 和方法 2 获得的瞬时功耗数据的时间积分。不够精细,无法与其他设备事件关联(但可能足以对设备电池寿命进行粗略估计)。

4.使用私有 Cocoa API 记录能源使用情况

由于我们只会在开发过程中这样做,因此 Apple 是否会拒绝该应用程序使用私有 API 并不重要。大概有一些专用 API 来解决这个问题,因为 Apple 能够在开启 Untethered Energy Diagnostics 的情况下记录数据。

优点:

  • 任意粒度、任意文件格式、任意持久性。

缺点:

  • Waaaaay 需要更多的工作来弄清楚如何使用它。也许甚至不可能。

5.组合方法

我们可以使用不受限制的诊断来量化每个操作的边际能源成本。 “好的,启动 GPS 天线需要 150mW•H。计算位置需要 50mW•H。发送 Mixpanel 事件需要 25mW•H,除非我们在前 30 秒内再次进行网络调用,在这种情况下需要 15mW•H。” (所有数字都是当场发明的。)然后我们可以使用系留监控来记录每个动作发生的时间,插入线性方程,并估计它应该消耗的能量 已经采取了。

优点:

  • 灵活。随心所欲。

缺点:

  • 数学。
  • 很容易错过非线性贡献。得到 E = k0/(gps 轮询间隔) + k1*(分析调用次数) 之类的东西很容易,但如果旋转两个天线的成本低于分别旋转它们的总和怎么办?
  • 忽略 Apple 可能在定位服务内部制定的任何缓存策略。
  • 甚至与现实世界的利用率相差甚远。

不管怎样,我已经说够了。以前有人做过吗?怎么样?

【问题讨论】:

  • 太宽泛了?你认为也许他需要添加更多细节?
  • 是的,如果有的话,我认为这个问题太具体了。我只是想抢占一些我迄今为止尝试过的明显但不足的解决方案。
  • 你说的“电池消耗是通过屋顶”是什么意思电池可以持续多少小时?
  • 你是怎么解决这个问题的?

标签: ios cocoa-touch gps instruments battery


【解决方案1】:

不确定这是否适用于这个确切的用例,但我开发了一个名为 UIDeviceListener 的库,它允许您轻松(基本上使用一行代码)从操作系统中检索有关功耗的数据和许多其他电池/充电相关数据点:https://github.com/eldoogy/PowerData

这是一个示例字典,可让您了解可以获取的信息类型。我会将您的注意力指向 InstantAmperage 键。这显示了整个设备(拔下设备时)的实时功耗(以 mA 为单位)。这可能有助于完成您在此处寻找的内容。

{
AdapterDetails =     {
    Amperage = 1000;
    Description = "usb host";
    FamilyCode = "-536854528";
    PMUConfiguration = 1000;
    Watts = 5;
};
AdapterInfo = 16384;
Amperage = 1000;
AppleRawCurrentCapacity = 1279;
AppleRawMaxCapacity = 1275;
AtCriticalLevel = 0;
AtWarnLevel = 0;
BatteryData =     {
    BatterySerialNumber = REDACTED;
    ChemID = 355;
    CycleCount = 524;
    DesignCapacity = 1420;
    Flags = 640;
    FullAvailableCapacity = 1325;
    ManufactureDate = REDACTED;
    MaxCapacity = 1273;
    MfgData = REDACTED;
    QmaxCell0 = 1350;
    StateOfCharge = 100;
    Voltage = 4194;
};
BatteryInstalled = 1;
BatteryKey = "0003-default";
BootBBCapacity = 52;
BootCapacityEstimate = 2;
BootVoltage = 3518;
CFBundleIdentifier = "com.apple.driver.AppleD1815PMU";
ChargerConfiguration = 990;
CurrentCapacity = 1275;
CycleCount = 524;
DesignCapacity = 1420;
ExternalChargeCapable = 1;
ExternalConnected = 1;
FullyCharged = 1;
IOClass = AppleD1815PMUPowerSource;
IOFunctionParent64000000 = <>;
IOGeneralInterest = "IOCommand is not serializable";
IOInterruptControllers =     (
    IOInterruptController34000000,
    IOInterruptController34000000,
    IOInterruptController34000000,
    IOInterruptController34000000
);
IOInterruptSpecifiers =     (
    <03000000>,
    <26000000>,
    <04000000>,
    <24000000>
);
IOMatchCategory = AppleD1815PMUPowerSource;
IOPowerManagement =     {
    CurrentPowerState = 2;
    DevicePowerState = 2;
    MaxPowerState = 2;
};
IOProbeScore = 0;
IOProviderClass = AppleD1815PMU;
InstantAmperage = 0;
IsCharging = 0;
Location = 0;
Manufacturer = A;
MaxCapacity = 1275;
Model = "0003-A";
Serial = REDACTED;
Temperature = 2590;
TimeRemaining = 0;
UpdateTime = 1461830702;
Voltage = 4182;
"battery-data" =     {
    "0003-default" = <...>;
    "0004-default" = <...>;
    "0005-default" = <...};
"built-in" = 1;
}

UIDeviceListener 支持常规的、非越狱的 iOS 设备,并且不调用任何私有 API。

【讨论】:

    【解决方案2】:

    我无法对在 iOS 上进行功耗测量提出建议,但可以指出一些可能的功耗来源,以及在进行测量时要考虑的一些问题。

    过度耗电的常见来源:

    • 轮询而不是使用中断。这可以防止处理器进入低功耗状态。低功耗状态可以将处理器消耗降低一个数量级以上

    • 使用太小的中断间隔。一个常见的错误是认为较小的轮询间隔(例如 10 毫秒)会导致更快的响应。如果您的应用/用户的响应能力为 500 毫秒,那么 10 毫秒仅用于保持处理器处于唤醒状态并消耗能量。

    • 任何传输的东西都是猪,接收较少但仍然很糟糕(WiFi、GPS、蓝牙等,如上所述)。尽量减少它们的使用。

    • 外设也有低功耗状态。谨慎使用它们以使它们保持在较低的功率状态。

    关于测量功耗的评论:

    • 监控本身会导致功耗过大。监控电源非常棘手。监控使用中断或轮询,使处理器/设备保持清醒并处于高功率状态。

    • 大多数监控来自操作系统,可能来自“真实”硬件测量与软件“猜测”,也可能不来自。

    • 尝试真正准确意味着更频繁的测量,您猜对了,这会导致处理器和设备保持清醒。

    我建议您仔细查看您真正需要的采样间隔,并设计您的应用以允许处理器和设备尽可能地休息。

    【讨论】:

      【解决方案3】:

      GPS 每小时需要 10% 的电量,因此每秒一次的高精度定位记录可以持续约 10 小时。位置轮询间隔与电池消耗无关。 GPS芯片是否启用。没有低功耗gps模式!!如果你知道用户不需要它,你可以禁用它。

      对于位置数据的永久记录,如果您决定使用低精度(1000m 蜂窝塔或无线局域网定位)而不是高精度(3-6m = GPS),则只能节省电池

      当然,在测量过程中,您会杀死所有 3d 派对应用程序,尤其是即时通讯应用程序,最著名的应用程序每秒都会连接到互联网!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-09
        • 1970-01-01
        • 2011-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多