Ask the updater to check for firmware from a button #60
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/check-for-updates-button"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
One button on the bridge that posts to the updater's
POST /api/checkand then refreshes what the firmware entities show. The update platform has no check of its own, and one button covers the van because a check polls for every node type at once.A check gets a long timeout of its own: the updater answers only when its downloads finish. Anything that leaves the entities looking as if nothing new was published — an unreachable repository, an image not fetched whole — is raised rather than swallowed.
Base is
feat/firmware-updates, notmain. CCS-UHA-8. The uplink-case part of the ticket is split out: the control API does not report it.Three things, then a note on the description.
@ -0,0 +48,4 @@_attr_translation_key = KEY# Config rather than diagnostic: this one changes something, which is the# line Home Assistant draws._attr_entity_category = EntityCategory.CONFIGEntityCategory.CONFIGkeeps the button off the default dashboard strategy and out of assistant exposure, while the update entities it exists to serve carry no category. On the Pi kiosk it will only be reachable from the device page, beside nothing it relates to. Dropping the category would put it where the firmware entities are.@ -0,0 +81,4 @@"checked. The van may have no uplink.")if outcome.failed:_LOGGER.info(outcome.failedonly reaches the log, so a check where the registry offered an image that could not be downloaded whole looks to the user exactly like a check that found nothing new — the same confusionregistry_reachedis raised for. Surface it the same way (refresh first, then raise naming the assets), or at least log it at warning, and cover it with a test: nothing exercises this branch today.@ -808,0 +1041,4 @@with patch.object(client, "_request", record):await client.async_check()assert asked == [firmware.CHECK_TIMEOUT]This patches
_request, so it provesasync_checkpassesCHECK_TIMEOUTbut never that_requesthands it to aiohttp.aioclient_mockswallowstimeoutand does not record it, so revertingtimeout=patiencetotimeout=REQUEST_TIMEOUTinfirmware.pykeeps the whole suite green — and that revert is precisely the trap the ticket names. Assert against a mocked session instead.The description: CLAUDE.md asks for a subject and a couple of short lines only where a reviewer needs them. This is five paragraphs, and the timeout,
async_refreshandregistry_reachedreasoning is already in the code comments. Trim to the base branch note, the ticket, and what was split out.All four taken.
failednow raises, after the refresh, so whatever did come down is showing by the time the message is read. Covered bytest_a_check_that_could_not_fetch_an_image_names_what_it_missed.async_get_clientsessionwith a session that records what each request was given, so_requestruns for real. Revertingtimeout=patiencetotimeout=REQUEST_TIMEOUTfails it; checked.All four taken. Two small things left, neither blocking.
On splitting the entity category out of
328d3eb: the branch is unmerged and this repo already keeps "Take the review" commits, so amend the message and force-push rather than leaving a PR comment as the only record of what is in that commit.@ -0,0 +40,4 @@state it does not keep."""# No entity category: this is not a setting and not a diagnostic, it isThis comment sits on
_attr_translation_key, which it is not about. Move it into the class docstring — a comment about an attribute that is deliberately absent has nothing to attach to.@ -808,0 +925,4 @@device_identifier(identifiers.OURS), van.entry_id)assert bridge is not Noneassert entry_for(hass, check_button(hass)).device_id == bridge.idWorth
assert entry_for(hass, check_button(hass)).entity_category is Nonehere. Where the button shows up is the behaviour that just changed, and nothing fails ifEntityCategory.CONFIGcomes back.@ -808,0 +1091,4 @@async def test_a_check_is_given_far_longer_than_a_request_that_answers_at_once(hass: HomeAssistant,aioclient_mock: AiohttpClientMocker,aioclient_mockdoes nothing here now. The fixture patcheshomeassistant.helpers.aiohttp_client._async_create_clientsession, and this test patchesfirmware.async_get_clientsessionoutright, so no session is ever created through it. Drop the fixture and the docstring line at 1102 with it — "the mocker is asked for only because that is what leaves the real client in place" is the opposite of what the mocker does.87ba446a58718f0a7d82Round two taken, head is now
718f0a7(force-pushed: the fetch-failure commit's message now says it drops the category too, as asked).aioclient_mock: it is not dead, it is load-bearing.no_real_updaterinconftest.pystubsUpdaterClient._requestout for any test that does not ask for the mocker, and_requestis exactly what this test exercises — without the fixture it fails with "no updater in tests". The docstring said that badly; it now names the fixture and says nothing answers through the mocker.Clean at
718f0a7, nothing further from me.My call on
aioclient_mockbeing dead was wrong:no_real_updateris autouse and keyed on the fixture name, so the test does need it.