Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

battery

UPower: system battery charge, state and time estimates, plus peripheral batteries.

text {
    content = mantle.battery:map(function(battery)
        local seconds = battery.present and battery.time_to_empty
        if not seconds then
            return ""
        end
        return string.format("%d:%02d left", seconds // 3600, seconds % 3600 // 60)
    end, ""),
}

State

mantle.battery:get() returns BatteryState, nil before the first push. A field marked ? may be absent.

mantle.battery’s payload. Without a system battery, present = false; peripherals may remain.

FieldTypeDescription
health?integerBattery health: full charge as a percent of design capacity, 0 to 100, combined over the system batteries. nil when UPower reports no design capacity.
percentintegerUPower’s Percentage, rounded to 0 to 100; a spurious 0 while not draining keeps the last value.
peripheralsPeripheralBattery[]UPower batteries outside the system supply, ordered by object path. This may include devices also shown by mantle.bluetooth.
presentbooleanUPower’s display device is a present battery. Check it before drawing system charge, state or time estimates.
stateBatteryStatusWhat the battery is doing; see BatteryStatus.
time_to_empty?integerSeconds until flat, or nil while UPower has no estimate.
time_to_full?integerSeconds until full, or nil while UPower has no estimate.

BatteryStatus

battery.state: UPower’s Device.State by name, e.g. b.state == "pending_charge".

ValueDescription
"unknown"No answer: UPower unreachable, an unknown state number, or a device without a battery state.
"charging"Taking current from an adapter.
"discharging"Draining.
"empty"Flat.
"fully_charged"Charged and holding.
"pending_charge"On mains, neither draining nor taking current: a charge limit, weak charger or thermal pause.
"pending_discharge"Waiting to discharge.

PeripheralBattery

One UPower battery outside the system supply.

FieldTypeDescription
icon?stringUPower icon name, or nil when absent.
idstringUPower object path; stable only while this UPower owner holds the device.
kindstringUPower device type, e.g. "mouse", "keyboard", "headset".
level?stringCoarse charge level, including "unknown", or nil when UPower says to use percent.
namestringUPower model, vendor, or object name.
percent?integerCharge percentage, or nil when UPower reports a coarse level or has no usable reading.
stateBatteryStatusCharge state; "unknown" when UPower has no recognized value.

Actions

None: read-only, so any method but get, map and on_change raises.

Backend

ContractBehavior
SourceUPower’s DisplayDevice for the system battery; EnumerateDevices for peripherals and health, which sums each system battery’s EnergyFull over its EnergyFullDesign because DisplayDevice reports no design capacity
UpdatesRe-reads the display device on PropertiesChanged; follows peripheral add, remove and property changes; retries failed enumeration after one second
No system batterypresent = false, percent = 0, state = "unknown", no time estimates; peripherals may remain
No UPowerThe same display defaults, with peripherals = {}

How do I…

Show a battery label

before stands in for the first push, so fn needs no nil guard.

text {
    foreground = mantle.battery:map(function(battery)
        return (battery.present and battery.percent <= 15) and "#F38BA8" or "#CDD6F4"
    end, "#CDD6F4"),
    content = mantle.battery:map(function(battery)
        if not battery.present then
            return ""
        end
        return string.format("%d%%%s", battery.percent, battery.state == "charging" and " +" or "")
    end, "…"),
}

See also: Battery indicator recipe; power for on-battery and power draw.

Source: supervisor/src/capabilities/battery/