You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: repair the dead stable channel and clear the review findings (#2)
* fix: repoint the stable channel at the published OTA manifest
The stable manifest URL 404s: neither
Faikin-S3-MINI-N4-R2-manifest.json (what we shipped) nor the
Faikout- spelling exists on ota.faikout.uk. Every stable-channel
user has been getting UpdateFailed on every refresh since v0.1.0.
The published stable manifest is Faikout.manifest -- same
"id": "Faikout-S3-MINI-N4-R2", self-referential url, and an
app: true entry pointing at Faikout-S3-MINI-N4-R2.bin. Verified
end to end: manifest -> app image -> HTTP 206 -> version c763929d.
The bug hid because the only live check skipped on any
FirmwareFetchError, so a 404 looked identical to an offline OTA
server. Split FirmwareUnavailableError out of FirmwareFetchError
for the case where the host never answered, and skip only on that
-- a bad status now fails the run. Nothing in CI ran that check at
all, so add a nightly OTA job to the Validate workflow, off the PR
path so an upstream outage blocks nobody.
Also in the OTA client, since the exception split touched it:
- Bound the Range-ignored fallback to 512 bytes. A server that
answers 200 instead of 206 was having its whole ~1.5 MB image
buffered, defeating the point of the ranged request.
- Fold the duplicated except-wrapper into one _fetch helper.
- Replace a tautological `assert session.closed is False` (the
fake never had a close()) with a real close-contract test.
* fix: collapse the channel onto entry.options and fix partial-failure logging
Remediation of the outstanding two-axis review findings.
Config entry (schema v2, with migration):
- The channel was written to entry.data at creation and to
entry.options on change, so every reader consulted both -- three
differently-defaulted spellings of the same lookup. It now lives
in options alone; async_migrate_entry moves v1 entries across,
preferring the options value as the one the user last chose, and
refuses an entry from a newer release rather than guessing.
- The config flow never checked MQTT, though the design requires an
abort. It does now, once per flow on the way to the form rather
than again on submit -- async_wait_for_mqtt_client can block for
up to 50s while MQTT is still setting up.
Coordinator logging:
- A wholly-failed refresh is now left entirely to
DataUpdateCoordinator, which already logs it once down and once
recovered; we were logging it a second time alongside.
- A *partial* failure counts as a successful refresh, so the base
class says nothing and a missing target was invisible above
debug. Those are reported here instead: unreachable-host warns
once per outage with a matching recovery, while a 404 or bad
metadata warns every refresh -- warn-once-then-silence is exactly
how the dead stable manifest stayed hidden for two months.
- UpdateFailed could render "...: None" when a channel resolved to
no URLs at all; that case gets its own translated message.
Smaller cleanups:
- binary_sensor reached into the config entry for a channel the
coordinator already holds; it now asks the coordinator, and the
four repeated tracker lookups collapse into one _device property.
- Guard the options read so an entry without a channel falls back
to stable instead of raising KeyError out of setup.
The design doc is updated to match on the two points settled by
decision -- the Gold quality target (it said Silver) and the
coordinator's deliberate whole-table iteration -- plus the
FirmwareUnavailableError split and the corrected logging contract.
* chore: release 0.2.0
Config entries move to schema v2 (channel in options, with
migration) and the stable channel URL changes, so this is not a
patch release.
0 commit comments