diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 6d7f8e3c7..b9f944f33 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -214,7 +214,11 @@ class MeshService : Service(), Logging { private var mqttMessageFlow: Job? = null private val batteryPercentUnsupported = 0.0 - private val batteryPercentLowThreshold = 20.0 + private val batteryPercentLowThreshold = 20 + private val batteryPercentLowDivisor = 5 + private val batteryPercentCriticalThreshold = 5 + private val batteryPercentCooldownSeconds = 1500 + private val batteryPercentCooldowns: HashMap = HashMap() private fun getSenderName(packet: DataPacket?): String { val name = nodeDBbyID[packet?.from]?.user?.longName @@ -949,9 +953,18 @@ class MeshService : Service(), Logging { val isRemote = (fromNum != myNodeNum) if (fromNum == myNodeNum || (isRemote && it.isFavorite)) { if (t.deviceMetrics.voltage > batteryPercentUnsupported && - t.deviceMetrics.batteryLevel < batteryPercentLowThreshold) { - serviceNotifications.showOrUpdateLowBatteryNotification(it, isRemote) + t.deviceMetrics.batteryLevel <= batteryPercentLowThreshold + ) { + if (shouldBatteryNotificationShow(fromNum, t)) { + serviceNotifications.showOrUpdateLowBatteryNotification( + it, + isRemote + ) + } } else { + if (batteryPercentCooldowns.containsKey(fromNum)) { + batteryPercentCooldowns.remove(fromNum) + } serviceNotifications.cancelLowBatteryNotification(it) } } @@ -962,6 +975,32 @@ class MeshService : Service(), Logging { } } + private fun shouldBatteryNotificationShow(fromNum: Int, t: TelemetryProtos.Telemetry): Boolean { + val isRemote = (fromNum != myNodeNum) + var shouldDisplay = false + var forceDisplay = false + when { + t.deviceMetrics.batteryLevel <= batteryPercentCriticalThreshold -> { + shouldDisplay = true + forceDisplay = true + } + t.deviceMetrics.batteryLevel == batteryPercentLowThreshold -> shouldDisplay = true + t.deviceMetrics.batteryLevel.mod(batteryPercentLowDivisor) == 0 && !isRemote -> shouldDisplay = true + isRemote -> shouldDisplay = true + } + if (shouldDisplay) { + val now = System.currentTimeMillis() / 1000 + if (!batteryPercentCooldowns.containsKey(fromNum)) batteryPercentCooldowns[fromNum] = 0 + if ((now - batteryPercentCooldowns[fromNum]!!) >= batteryPercentCooldownSeconds || + forceDisplay + ) { + batteryPercentCooldowns[fromNum] = now + return true + } + } + return false + } + private fun handleReceivedPaxcounter(fromNum: Int, p: PaxcountProtos.Paxcount) { updateNodeInfo(fromNum) { it.paxcounter = p } }