BatteryDropCondition.swift 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. // LoopFollow
  2. // BatteryDropCondition.swift
  3. // Created by Jonas Björkert.
  4. import Foundation
  5. /// Fires when the phone-battery **falls by ≥ Δ % within N minutes**.
  6. ///
  7. /// * `alarm.delta`   ➜ percentage drop (e.g. 5 %)
  8. /// * `alarm.monitoringWindow` ➜ window in minutes (e.g. 15)
  9. /// * Uses `data.batteryHistory`, which must be sorted **oldest → newest**.
  10. struct BatteryDropCondition: AlarmCondition {
  11. static let type: AlarmType = .batteryDrop
  12. init() {}
  13. func evaluate(alarm: Alarm, data: AlarmData, now _: Date) -> Bool {
  14. // ───── 0. sanity ───────────────────────────────────────────────
  15. guard
  16. let drop = alarm.delta, drop > 0,
  17. let minutes = alarm.monitoringWindow, minutes > 0,
  18. let latest = data.batteryHistory.last
  19. else { return false }
  20. // find the sample *closest* to “minutes” ago
  21. let target = latest.timestamp.addingTimeInterval(-Double(minutes) * 60)
  22. guard let earlier = data.batteryHistory.min(by: {
  23. abs($0.timestamp.timeIntervalSince(target)) < abs($1.timestamp.timeIntervalSince(target))
  24. }) else { return false }
  25. // ignore if the earlier level was 100 % (false drop when just unplugged)
  26. guard earlier.batteryLevel < 100 else { return false }
  27. return (earlier.batteryLevel - latest.batteryLevel) >= drop
  28. }
  29. }