Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Battery and next alarm sensor improvements #740

Merged
merged 2 commits into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -21,9 +21,11 @@ open class HomeAssistantApplication : Application(), GraphComponentAccessor {

// This will cause the sensor to be updated every time the OS broadcasts that a cable was plugged/unplugged.
// This should be nearly instantaneous allowing automations to fire immediately when a phone is plugged
// in or unplugged.
// in or unplugged. Updates will also be triggered when the system reports low battery and when it recovers.
registerReceiver(
ChargingBroadcastReceiver(appComponent.integrationUseCase()), IntentFilter().apply {
addAction(Intent.ACTION_BATTERY_LOW)
addAction(Intent.ACTION_BATTERY_OKAY)
addAction(Intent.ACTION_POWER_CONNECTED)
addAction(Intent.ACTION_POWER_DISCONNECTED)
}
Expand Down
Expand Up @@ -99,11 +99,15 @@ class BatterySensorManager : SensorManager {

val percentage: Int = getBatteryPercentage(level, scale)

val isCharging = getIsCharging(intent)
val chargerType = getChargerType(intent)
val chargingStatus = getChargingStatus(intent)

return Sensor(
"battery_level",
percentage,
"sensor",
getBatteryIcon(percentage),
getBatteryIcon(percentage, isCharging, chargerType, chargingStatus),
mapOf()
)
}
Expand All @@ -118,35 +122,61 @@ class BatterySensorManager : SensorManager {
return null
}

val isCharging: Boolean = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL
val isCharging = getIsCharging(intent)
val chargerType = getChargerType(intent)
val chargingStatus = getChargingStatus(intent)
val batteryHealth = getBatteryHealth(intent)

val percentage: Int = getBatteryPercentage(level, scale)

return Sensor(
"battery_state",
chargingStatus,
"sensor",
getBatteryIcon(percentage, isCharging, chargerType, chargingStatus),
mapOf(
"is_charging" to isCharging,
"charger_type" to chargerType,
"battery_health" to batteryHealth
)
)
}

private fun getIsCharging(intent: Intent): Boolean {
val status: Int = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)

return status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL
}

val chargerType: String = when (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)) {
private fun getChargerType(intent: Intent): String {
return when (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)) {
BatteryManager.BATTERY_PLUGGED_AC -> "ac"
BatteryManager.BATTERY_PLUGGED_USB -> "usb"
BatteryManager.BATTERY_PLUGGED_WIRELESS -> "wireless"
else -> "unknown"
}
}

val chargingStatus: String = when (status) {
private fun getChargingStatus(intent: Intent): String {
return when (intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1)) {
BatteryManager.BATTERY_STATUS_FULL -> "full"
BatteryManager.BATTERY_STATUS_CHARGING -> "charging"
BatteryManager.BATTERY_STATUS_DISCHARGING -> "discharging"
BatteryManager.BATTERY_STATUS_NOT_CHARGING -> "not_charging"
else -> "unknown"
}
}

val percentage: Int = getBatteryPercentage(level, scale)

return Sensor(
"battery_state",
chargingStatus,
"sensor",
getBatteryIcon(percentage, isCharging, chargerType, chargingStatus),
mapOf(
"is_charging" to isCharging,
"charger_type" to chargerType
)
)
private fun getBatteryHealth(intent: Intent): String {
return when (intent.getIntExtra(BatteryManager.EXTRA_HEALTH, -1)) {
BatteryManager.BATTERY_HEALTH_COLD -> "cold"
BatteryManager.BATTERY_HEALTH_DEAD -> "dead"
BatteryManager.BATTERY_HEALTH_GOOD -> "good"
BatteryManager.BATTERY_HEALTH_OVERHEAT -> "overheated"
BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE -> "over_voltage"
BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE -> "failed"
else -> "unknown"
}
}
}
Expand Up @@ -7,6 +7,7 @@ import io.homeassistant.companion.android.domain.integration.IntegrationUseCase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class ChargingBroadcastReceiver(
Expand All @@ -18,6 +19,10 @@ class ChargingBroadcastReceiver(
updateJob?.cancel()
updateJob = ioScope.launch {
AllSensorsUpdaterImpl(integrationUseCase, context).updateSensors()
// Add a 5 second delay to perform another update so charging state updates completely.
// This is necessary as the system needs a few seconds to verify the charger.
delay(5000L)
AllSensorsUpdaterImpl(integrationUseCase, context).updateSensors()
}
}
}
Expand Up @@ -48,6 +48,7 @@ class NextAlarmManager : SensorManager {
var triggerTime = 0L
var local = ""
var utc = "unavailable"
var pendingIntent = ""

try {
val alarmManager: AlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
Expand All @@ -56,6 +57,7 @@ class NextAlarmManager : SensorManager {

if (alarmClockInfo != null) {
triggerTime = alarmClockInfo.triggerTime
pendingIntent = alarmClockInfo.showIntent.creatorPackage.toString()

val cal: Calendar = GregorianCalendar()
cal.timeInMillis = triggerTime
Expand All @@ -79,7 +81,8 @@ class NextAlarmManager : SensorManager {
icon,
mapOf(
"Local Time" to local,
"Time in Milliseconds" to triggerTime
"Time in Milliseconds" to triggerTime,
"Package" to pendingIntent
)
)
}
Expand Down