Feature Request: Expose per-battery data for dual-battery devices
Summary
Add a batteries property to RingDoorBell that returns structured per-battery information
for devices with one or more battery bays (e.g. Spotlight Cam Battery, Stickup Cam). The
existing battery_life property has a correctness bug for dual-battery devices that this
change would also fix.
Background / motivation
Several Ring devices (Spotlight Cam Battery, Stickup Cam, and others) have two battery bays
so that one battery can be swapped while the device stays powered. The Ring API already returns
rich per-battery data at two levels:
Top-level _attrs fields
"battery_life": "12",
"battery_life_2": "100"
health sub-object (richer)
"batteries": [
{
"battery_number": 1,
"battery_percentage": 12,
"battery_voltage": 3562.0,
"battery_percentage_category": "very_poor",
"battery_voltage_category": "good"
},
{
"battery_number": 2,
"battery_percentage": 100,
"battery_voltage": 4144.0,
"battery_percentage_category": "very_good",
"battery_voltage_category": "very_good"
}
],
"active_battery": 1
Current battery_life bug
doorbot.py:158-173 sums both percentages and caps at 100:
value = 0
if bl1:
value += int(bl1)
if bl2 := self._attrs.get("battery_life_2"):
value += int(bl2)
return min(value, 100)
For battery_1 = 12 %, battery_2 = 100 %, this returns min(112, 100) = 100, hiding that the
active battery is nearly dead.
battery_life_2 is also not exposed as a public property at all, so library consumers have no
way to surface the second battery without reaching into private state.
Proposed change
1. Add a batteries property
Return the structured list from health.batteries. On single-battery devices this list has one
entry; on dual-battery devices it has two. This makes the API future-proof for any number of
battery bays.
@property
def batteries(self) -> list[dict] | None:
"""Return per-battery data from the health payload, or None if unavailable."""
health = self._attrs.get("health", {})
return health.get("batteries") or None
Suggested return shape (matches what the API already provides):
[
{
"battery_number": 1,
"battery_percentage": 12,
"battery_voltage": 3562.0,
"battery_percentage_category": "very_poor",
"battery_voltage_category": "good",
},
...
]
Also consider exposing health.get("active_battery") as a companion property so consumers
can surface which bay is currently powering the device.
2. Fix battery_life for dual-battery devices
Change battery_life to return the active battery's percentage (i.e. _attrs["battery_life"]
directly) instead of the broken sum. The active battery is always reported as battery_life at
the top level, so the fix is simply:
@property
def battery_life(self) -> int | None:
"""Return battery life."""
bl = self._attrs.get("battery_life")
if bl is None and "battery_life_2" not in self._attrs:
return None
return int(bl) if bl is not None else None
This is a bug fix with a narrow breaking-change risk: integrations that relied on the
summed/capped value would see a lower (but correct) number for dual-battery devices.
Why not just add a battery_life_2 property?
A second flat property works for today's two-bay devices but doesn't generalise and still
requires consumers to implement their own "which batteries are present?" logic. The batteries
list from health is already structured, supports any count, and includes voltage and category
information that a flat property cannot carry. The list is the right public API.
Downstream benefit
Home Assistant's Ring integration currently exposes a single battery sensor. With a batteries
property (and a corrected battery_life) it can:
- Show one sensor per battery bay, dynamically, with no magic numbers.
- Expose the
active_battery index as a device attribute.
- Correctly warn users when the active battery is critically low even if the reserve is full.
Acceptance criteria
Feature Request: Expose per-battery data for dual-battery devices
Summary
Add a
batteriesproperty toRingDoorBellthat returns structured per-battery informationfor devices with one or more battery bays (e.g. Spotlight Cam Battery, Stickup Cam). The
existing
battery_lifeproperty has a correctness bug for dual-battery devices that thischange would also fix.
Background / motivation
Several Ring devices (Spotlight Cam Battery, Stickup Cam, and others) have two battery bays
so that one battery can be swapped while the device stays powered. The Ring API already returns
rich per-battery data at two levels:
Top-level
_attrsfieldshealthsub-object (richer)Current
battery_lifebugdoorbot.py:158-173sums both percentages and caps at 100:For battery_1 = 12 %, battery_2 = 100 %, this returns
min(112, 100) = 100, hiding that theactive battery is nearly dead.
battery_life_2is also not exposed as a public property at all, so library consumers have noway to surface the second battery without reaching into private state.
Proposed change
1. Add a
batteriespropertyReturn the structured list from
health.batteries. On single-battery devices this list has oneentry; on dual-battery devices it has two. This makes the API future-proof for any number of
battery bays.
Suggested return shape (matches what the API already provides):
[ { "battery_number": 1, "battery_percentage": 12, "battery_voltage": 3562.0, "battery_percentage_category": "very_poor", "battery_voltage_category": "good", }, ... ]Also consider exposing
health.get("active_battery")as a companion property so consumerscan surface which bay is currently powering the device.
2. Fix
battery_lifefor dual-battery devicesChange
battery_lifeto return the active battery's percentage (i.e._attrs["battery_life"]directly) instead of the broken sum. The active battery is always reported as
battery_lifeatthe top level, so the fix is simply:
This is a bug fix with a narrow breaking-change risk: integrations that relied on the
summed/capped value would see a lower (but correct) number for dual-battery devices.
Why not just add a
battery_life_2property?A second flat property works for today's two-bay devices but doesn't generalise and still
requires consumers to implement their own "which batteries are present?" logic. The
batterieslist from
healthis already structured, supports any count, and includes voltage and categoryinformation that a flat property cannot carry. The list is the right public API.
Downstream benefit
Home Assistant's Ring integration currently exposes a single
batterysensor. With abatteriesproperty (and a corrected
battery_life) it can:active_batteryindex as a device attribute.Acceptance criteria
RingDoorBell.batteriesreturns alist[dict](one entry per bay) whenhealth.batteriesis present, and
Noneotherwise.battery_number,battery_percentage,battery_voltage.battery_lifereturns the active battery's percentage (not the sum) for dual-battery devices.battery_lifecontinues to work;batteriesreturnsa one-element list.