Repository navigation
feat: add battery_status property to Tile - #792
Merged
Merged
Conversation
The Tile API returns a battery status on every tile detail response, but the `Tile` object defines no property for it, so consumers cannot reach it without touching `_tile_data` directly. This closes bachya#107. The field is already present in this repo's own test fixtures (`tile_details_response.json` and `tile_details_missing_last_state_response.json` both carry `"battery_status": "NONE"`), so no fixture changes were needed. Observed against a live account with six Tiles: values are `NONE`, `LEVEL1` and `LEVEL2`, and whether a Tile reports a level at all depends on its firmware generation. The `05.x` firmware reported `LEVEL1`/`LEVEL2` while `40.x`/`42.x`/`43.x` reported `NONE`, so a missing level is normal rather than an error. The property uses `.get()` and is typed `str | None` accordingly. Note on `last_tile_state.battery_level`, also requested in bachya#107: it is deliberately not added here. Across those same six Tiles it read exactly `0.0` on every poll, and this repo's fixture carries `0` as well. It appears to be a key Tile populates but never writes to, so exposing it would invite consumers to build low-battery logic on a value that is always zero. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qui3EQaoxiVRCBVVe9waLw
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #792 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 5 5
Lines 178 181 +3
=========================================
+ Hits 178 181 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
bachya
approved these changes
Sep 22, 2026
Adding `battery_status` took `Tile` to 21 public methods, one past pylint's default of 20, which failed the Linting & Static Analysis job. `Tile` exposes one read-only property per API field, so its method count tracks the API surface rather than any design problem. Silence R0904 on the class with an inline disable, matching how `API.__init__` already handles `too-many-arguments`, instead of loosening the limit project-wide. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qui3EQaoxiVRCBVVe9waLw
Contributor
Author
|
Thanks for the quick review. The pylint R0904 failure is fixed in 708d6c5, and pylint, ruff, isort, mypy and the tests all pass locally. The workflows on that commit are waiting for maintainer approval to run. |
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Describe what the PR does:
Adds a
battery_statusproperty to theTileobject, plus itsas_dict()entry andREADME.mddocumentation.The Tile API returns a battery status on every tile detail response, but
Tiledefinesno property for it, so consumers cannot reach it without touching
_tile_datadirectly. The field is already present in this repo's own fixtures — both
tile_details_response.jsonandtile_details_missing_last_state_response.jsoncarry"battery_status": "NONE"— so no fixture changes were needed.Observed values
Checked against a live account with six Tiles. Values are
NONE,LEVEL1andLEVEL2, and whether a Tile reports a level at all depends on its firmware generation:battery_status05.04.03.0LEVEL205.04.03.0LEVEL140.04.10.0NONE42.04.10.0NONE43.04.10.0NONEBecause a missing level is normal rather than an error, the property uses
.get()andis typed
str | None.On
last_tile_state.battery_level#107 asked for a battery level too. I have deliberately left it out, and wanted to
show the evidence rather than just omit it silently.
Across those same six Tiles it read exactly
0.0on every poll, on both firmwaregenerations. This repo's own fixture carries
0as well. It looks like a key Tilepopulates but never writes to. Exposing it would invite consumers to build low-battery
logic on a value that is always zero — which is a worse failure than the field simply
being absent, since it reads as a flat battery.
Happy to add it in a follow-up if you would rather the library mirror the full API
surface and leave that judgement to callers.
Update:
LEVEL1is the lower stateA third battery location settles this:
result.metadata, which neither the currentproperties nor this PR touch.
metadata.battery_statemetadata.battery_replaced_atbattery_status"50"LEVEL2"40"LEVEL1"10"NONEbattery_statetracksbattery_status, andLEVEL1sits belowLEVEL2. That is twodata points, so I have kept the docstring descriptive rather than hard-coding a mapping.
battery_stateis a modelled estimate, not a reading. The Wallet above had not reportedfor 406 days, which means its cell was flat, and it still reads
"40". The three"10"values are identical across Tiles activated on different dates, and this repo'sown
tile_details_response.jsonalso carries"battery_state": "10"next to"battery_status": "NONE". That makes10look like a placeholder for "no data".battery_replaced_atis the more useful of the two. If you want them, I can open aseparate PR for the
metadatafields and keep this one to what you approved.CI: the pylint failure was R0904 (
Tilewent to 21 public methods against thedefault limit of 20).
708d6c5adds an inline disable on the class, following the samepattern as
API.__init__'stoo-many-arguments, so the project-wide limit stays as itis. pylint, ruff, isort, mypy and the tests all pass locally.
Does this fix a specific issue?
Fixes #107
Checklist:
README.mdwith any new documentation.Verified locally on Python 3.12: 12 passed,
pytile/tile.pyat 100% coverage(181/181 statements overall),
ruff checkclean,ruff formatclean,mypyclean.🤖 Generated with Claude Code
https://claude.ai/code/session_01Qui3EQaoxiVRCBVVe9waLw