fix(discovery): a sweep that could not run is not an answer (t62 F1)
The installed-apps sweep stamped an EMPTY answer on every failure path, so a Shield that was asleep at the entity's startup sweep was cached as "0 apps" for APP_LIST_TTL (6 h): `homeassistant.update_entity` then issued zero shells and the sensor kept reporting 0/"pending" until the TTL or the Configure row's force. A genuinely empty device was indistinguishable from it, so "ok" was unreachable for an empty list. Only a sweep that RAN stamps the cache now. Every failure records the outcome as `unknown` (`_apps_unavailable`), stores no table, and is retried by the next non-forced refresh; a sweep that reached the device and failed is spaced by APP_SWEEP_RETRY_SECONDS (30 s, force=True bypasses) so a silent socket is not hammered once per poll, while an unavailable transport costs nothing and is retried immediately. `installed_apps_status` exposes ok/unknown/pending, the sensor surfaces it, and "ok" + an empty table is now the honest empty answer. Docstrings, the README vocabulary and the docs on what a refresh actually re-runs are corrected; the "update_entity re-runs only without a fresh table, the Configure row forces one" wording stays true. Red proof (pre-fix sources, current tests): the five new/updated tests fail on HEAD, e.g. `installed_apps_stale` is False after the ADB-down startup sweep, and the sensor reports 'pending' where it must say 'unknown'. Same class already fixed for app labels: a fetch that could not run is not an answer. Also records that the `-3`/resolve-activity/pm-dump output shapes are documented, not observed.
This commit is contained in:
1 parent
ef42682250
commit
c05e6fa929
4 files changed
+217
-43
No files matched your search
@@ -448,6 +448,12 @@ not launchable apps — with the one exception that matters: the active launcher
|
||||
is a system app yet is exactly what the user sees. Nothing else is filtered, so an app
|
||||
is missing only if Android itself does not report it.
|
||||
|
||||
*(Every output shape above is the **documented** Android one, not an observed
|
||||
capture: no real Shield was available when this was written, so
|
||||
`pm list packages -3`, `resolve-activity --brief` and `pm dump` are exercised from
|
||||
fixtures — the same "inferred, not observed" mark the state=6 buffering value
|
||||
carries in the source ladder above.)*
|
||||
|
||||
Names come from the same cached path the Current App sensor uses: a `pm dump` per
|
||||
package, parsed for `application-label`, cached for 24 h. A full sweep runs the dumps
|
||||
in a small burst (4 at a time, 50 ms apart), which finishes a typical Shield in
|
||||
@@ -466,16 +472,22 @@ and `mdi:television` otherwise. The icon never enters your **icon column**: that
|
||||
is a picture URL or a `camera.*` entity and feeds `entity_picture`, so writing an
|
||||
`mdi:` name there would put a value the media player cannot use into your own map.
|
||||
|
||||
Discovery never runs on a state poll: it happens when you press the row, and the result
|
||||
is cached for 6 h. With ADB off, or unreachable, the table simply shows the rows you
|
||||
wrote yourself and the menu says why.
|
||||
Discovery does not run on the watchdog: the Configure row runs it, the dashboard
|
||||
sensor refreshes the table when it has no fresh one, and the result is cached for 6 h.
|
||||
With ADB off, or unreachable, the table simply shows the rows you wrote yourself and
|
||||
the menu says why. A sweep that **could not run** is not cached as an answer: it is
|
||||
recorded as `unknown` and retried, so a Shield that was asleep at startup is picked up
|
||||
by the next refresh instead of reporting an empty device for six hours.
|
||||
|
||||
**For dashboards** the same table is a sensor: `sensor.<name>_installed_apps`, whose
|
||||
state is the app **count** and whose `installed_apps` attribute is the list of
|
||||
`{package, name, icon}`. Its `discovery` attribute says `ok`, `pending`, `not_connected`
|
||||
or `adb_disabled`. It only exists for ADB-enabled entries, and it is cheap to refresh —
|
||||
`homeassistant.update_entity` on it re-runs the sweep only when the cache has expired,
|
||||
while the Configure row forces one.
|
||||
`{package, name, icon}`. Its `discovery` attribute says `ok`, `pending`, `unknown`,
|
||||
`not_connected` or `adb_disabled`: `ok` means the table IS the answer — including a
|
||||
genuinely empty one — and `unknown` means the last sweep could not run (an empty list
|
||||
then says nothing about the device, and the next refresh retries). It only exists for
|
||||
ADB-enabled entries, and it is cheap to refresh — `homeassistant.update_entity` on it
|
||||
re-runs the sweep only when there is no fresh table (the cache expired, or the last
|
||||
sweep could not run), while the Configure row forces one.
|
||||
|
||||
```yaml
|
||||
# every installed app, with the name this integration would show
|
||||
|
||||
Reference in new issue
Block a user