1+ package com.valterc.ki2.karoo.battery
2+
3+ import com.valterc.ki2.R
4+ import com.valterc.ki2.data.device.BatteryInfo
5+ import com.valterc.ki2.data.device.DeviceId
6+ import com.valterc.ki2.data.device.DeviceName
7+ import com.valterc.ki2.data.preferences.PreferencesView
8+ import com.valterc.ki2.karoo.Ki2ExtensionContext
9+ import com.valterc.ki2.karoo.RideHandler
10+ import io.hammerhead.karooext.models.InRideAlert
11+ import io.hammerhead.karooext.models.RideState
12+ import io.hammerhead.karooext.models.SystemNotification
13+ import java.util.function.BiConsumer
14+ import java.util.function.Consumer
15+
16+ class BatteryAlertHandler (extensionContext : Ki2ExtensionContext ) : RideHandler(extensionContext) {
17+
18+ private var batteryLevelLow: Int? = null
19+ private var batteryLevelCritical: Int? = null
20+ private val notificationMap = mutableMapOf<DeviceId , BatteryAlertRecord >()
21+
22+ private val preferencesConsumer = Consumer <PreferencesView > { preferences ->
23+ batteryLevelLow = preferences.getBatteryLevelLow(extensionContext.context)
24+ batteryLevelCritical = preferences.getBatteryLevelCritical(extensionContext.context)
25+
26+ notificationMap.values.forEach { batteryRecord ->
27+ checkBatteryAndNotify(batteryRecord)
28+ }
29+ }
30+
31+ private val batteryConsumer = BiConsumer <DeviceId , BatteryInfo > { deviceId, batteryInfo ->
32+ notificationMap[deviceId]?.let { batteryRecord ->
33+ batteryRecord.batteryInfo = batteryInfo
34+ } ? : run {
35+ notificationMap[deviceId] = BatteryAlertRecord (deviceId, batteryInfo)
36+ }
37+
38+ notificationMap[deviceId]?.let { batteryRecord ->
39+ checkBatteryAndNotify(batteryRecord)
40+ }
41+ }
42+
43+ init {
44+ extensionContext.serviceClient.registerUnfilteredBatteryInfoWeakListener(batteryConsumer)
45+ extensionContext.serviceClient.registerPreferencesWeakListener(preferencesConsumer)
46+ }
47+
48+ override fun onRideStart () {
49+ notificationMap.values.forEach { batteryRecord ->
50+ checkBatteryAndNotify(batteryRecord)
51+ }
52+ }
53+
54+ override fun onRideResume () {
55+ notificationMap.values.forEach { batteryRecord ->
56+ checkBatteryAndNotify(batteryRecord)
57+ }
58+ }
59+
60+ override fun onRideEnd () {
61+ notificationMap.values.forEach { batteryRecord ->
62+ batteryRecord.alertedInRide = false
63+ }
64+ }
65+
66+ private fun checkBatteryAndNotify (batteryAlertRecord : BatteryAlertRecord ) {
67+ if (extensionContext.karooDeviceTracking.isDeviceConnected(batteryAlertRecord.deviceId)) {
68+ // If the device was added to Karoo, let Karoo handle the battery notification
69+ return
70+ }
71+
72+ batteryAlertRecord.batteryInfo?.let { batteryInfo ->
73+ val batteryLevelCritical = batteryLevelCritical
74+ val batteryLevelLow = batteryLevelLow
75+
76+ if (batteryLevelCritical != null && batteryInfo.value <= batteryLevelCritical) {
77+ notify(batteryAlertRecord, batteryInfo, BatteryAlertType .Critical )
78+ } else if (batteryLevelLow != null && batteryInfo.value <= batteryLevelLow) {
79+ notify(batteryAlertRecord, batteryInfo, BatteryAlertType .Low )
80+ }
81+ }
82+ }
83+
84+ private fun notify (
85+ batteryAlertRecord : BatteryAlertRecord ,
86+ batteryInfo : BatteryInfo ,
87+ batteryAlertType : BatteryAlertType
88+ ) {
89+ if (batteryAlertRecord.alert == batteryAlertType && batteryAlertRecord.alertedInRide) {
90+ return
91+ }
92+
93+ val devicePreferences =
94+ extensionContext.serviceClient.getDevicePreferences(batteryAlertRecord.deviceId)
95+ val deviceName =
96+ devicePreferences?.getName(extensionContext.context) ? : DeviceName .getDefaultName(
97+ extensionContext.context,
98+ batteryAlertRecord.deviceId
99+ )
100+ val title = extensionContext.context.getString(R .string.text_di2_low_battery)
101+ val detail = extensionContext.context.getString(
102+ R .string.text_param_low_battery,
103+ deviceName,
104+ batteryInfo.value
105+ )
106+
107+ if (! batteryAlertRecord.alertedInRide && rideState is RideState .Recording ) {
108+ batteryAlertRecord.alertedInRide = true
109+ extensionContext.karooSystem.dispatch(
110+ InRideAlert (
111+ " ki2-ride-alert-battery-${batteryAlertRecord.deviceId.uid} " ,
112+ R .drawable.ic_hh_battery,
113+ title,
114+ detail,
115+ 12_000 ,
116+ backgroundColor = R .color.hh_red_600,
117+ textColor = R .color.white
118+ )
119+ )
120+ extensionContext.audioManager.playKarooDeviceWarning()
121+ }
122+
123+ extensionContext.karooSystem.dispatch(
124+ SystemNotification (
125+ " ki2-notification-battery-${batteryAlertRecord.deviceId.uid} " ,
126+ detail,
127+ header = title,
128+ style = if (batteryAlertType == BatteryAlertType .Critical ) SystemNotification .Style .ERROR else SystemNotification .Style .EVENT
129+ )
130+ )
131+
132+ batteryAlertRecord.alert = batteryAlertType
133+ }
134+
135+ }
0 commit comments