Skip to content

Commit

Permalink
Add a remaining charge time sensor for supported devices (#4346)
Browse files Browse the repository at this point in the history
* Add a remaining charge time sensor for supported devices

* Send unavailable and convert to minutes

* Use correct unit of measurement

* Fix ms to min conversion and update title to match other sensor casing

* Round down instead of up
  • Loading branch information
dshokouhi committed May 3, 2024
1 parent 674f5d4 commit 38e5da1
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build
import androidx.annotation.RequiresApi
import io.homeassistant.companion.android.common.R as commonR
import io.homeassistant.companion.android.common.util.STATE_UNAVAILABLE
import io.homeassistant.companion.android.common.util.STATE_UNKNOWN
import java.math.RoundingMode
import kotlin.math.floor

class BatterySensorManager : SensorManager {

Expand Down Expand Up @@ -91,6 +95,17 @@ class BatterySensorManager : SensorManager {
entityCategory = SensorManager.ENTITY_CATEGORY_DIAGNOSTIC
)

private val remainingChargeTime = SensorManager.BasicSensor(
"remaining_charge_time",
"sensor",
commonR.string.basic_sensor_name_remaining_charge_time,
commonR.string.sensor_description_remaining_charge_time,
"mdi:battery-clock",
"duration",
unitOfMeasurement = "min",
entityCategory = SensorManager.ENTITY_CATEGORY_DIAGNOSTIC
)

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

Expand All @@ -106,16 +121,22 @@ class BatterySensorManager : SensorManager {
override val name: Int
get() = commonR.string.sensor_name_battery

private val defaultSensorList = listOf(
batteryLevel,
batteryState,
isChargingState,
chargerTypeState,
batteryHealthState,
batteryTemperature,
batteryPower
)

override suspend fun getAvailableSensors(context: Context): List<SensorManager.BasicSensor> {
return listOf(
batteryLevel,
batteryState,
isChargingState,
chargerTypeState,
batteryHealthState,
batteryTemperature,
batteryPower
)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
defaultSensorList.plus(remainingChargeTime)
} else {
defaultSensorList
}
}

override fun hasSensor(context: Context): Boolean {
Expand All @@ -139,6 +160,9 @@ class BatterySensorManager : SensorManager {
updateBatteryHealth(context, intent)
updateBatteryTemperature(context, intent)
updateBatteryPower(context, intent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
updateRemainingChargeTime(context)
}
}
}

Expand Down Expand Up @@ -301,6 +325,33 @@ class BatterySensorManager : SensorManager {
)
}

@RequiresApi(Build.VERSION_CODES.P)
private fun updateRemainingChargeTime(context: Context) {
if (!isEnabled(context, remainingChargeTime)) {
return
}

val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
val chargeTime = batteryManager.computeChargeTimeRemaining()
val remainingCharge = if (chargeTime >= 0) {
chargeTime.toFloat() / 60000f
} else {
STATE_UNAVAILABLE
}

onSensorUpdated(
context,
remainingChargeTime,
if (chargeTime >= 0) {
floor(remainingCharge as Float).toInt()
} else {
remainingCharge
},
remainingChargeTime.statelessIcon,
mapOf()
)
}

private fun getChargerType(intent: Intent): String {
return when (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)) {
BatteryManager.BATTERY_PLUGGED_AC -> "ac"
Expand Down
2 changes: 2 additions & 0 deletions common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1234,4 +1234,6 @@
<string name="state_sunny">Sunny</string>
<string name="state_windy">Windy</string>
<string name="feedback">Feedback</string>
<string name="basic_sensor_name_remaining_charge_time">Remaining charge time</string>
<string name="sensor_description_remaining_charge_time">Compute an approximation for how much time (in minutes) remains until the battery is fully charged. Returns unavailable if no time can be computed: either there is not enough current data to make a decision or the battery is currently discharging. Returns 0 if calculation is not complete but device is currently charging.</string>
</resources>

0 comments on commit 38e5da1

Please sign in to comment.