Skip to content

0.9.1 - #47

Merged
oleost merged 19 commits into
mainfrom
promote/0.9.1
Oct 15, 2026
Merged

oleost merged 19 commits into
mainfrom
promote/0.9.1

Conversation

@oleost

@oleost oleost commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Promote 0.9.1 (betas 0.9.1b1–b6) to stable. Release notes: the ## 0.9.1 entry in visionstate/CHANGELOG.md.

Checked on the test Home Assistant: CI and audits green, HA restart, host reboot, MQTT broker restart, app backup and restore (training images included), 1-hour soak (memory flat at ~678 MB, log quiet).

🤖 Generated with Claude Code

oleost and others added 19 commits October 12, 2026 22:28
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching the face model gave no sign on the start page or the sensor's page, and the taught faces
were embedded again in the middle of the first check, with no progress anywhere. Now they are
embedded as soon as the new model is loaded, with a count in the face status, and the model is used
only once they are done (the checks go on without faces meanwhile, as while it downloads). Object
sensors that recognise faces show Downloading / Loading / Learning faces… where state sensors show
Training…; the Faces card, People and Settings show the progress.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the counter

A fixed largest change between two readings was both too loose and too tight: issue #40's water
meter (0.04 m³ per one-minute reading, 2.4 m³/h) rejected right readings for good after a
35-minute update. A counter's limit is now a rate times the time it was not seen (the app down,
the camera away, readings unsure); time in which it was read clearly but too high does not count,
so a wheel misread over and over stays rejected. The limit starts again only when a reading
confirms the published value.

- "Learn it" (new counters): the busiest rise over 10 minutes and per day, second busiest of the
  last two weeks, times two, after a week of readings; learned from accepted readings (each with
  the lower of it and the next one), only over stretches where the counter was read all along.
- Readings over the limit that agree for 5 minutes are accepted, unless the jump is one wheel's
  step: those wait in Review.
- Read correctly (or a typed right value) on the newest rejected reading makes it the value; it
  is kept over a restart (reading_watch).
- Existing counters keep their limit as a rate (max_step per check interval), or none.

Replayed on issue #40's data (25 days, downtime, unsure stretches, stuck wheels): right readings
rejected for a too large change 30,764 -> 5, hours behind the meter 528 -> 31, no wrong value
published once learned. A live run with restarts passed all steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… is gone

- The counter limit test read the value right after a restart, before the first reading.
- The face download test read "loading" in the moment between the error being set and the
  loading task ending.
- Live and analysed frames revoked their blob URL while the image could still be loading it, which
  WebKit logs as a console error (the iPhone e2e run failed on it); it is let go a second later.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Learn it" set no limit until it had a week of readings: on issue #40's water
meter a wheel read two digits off went through as +2.09 m³. Until learned it
now takes max_rate, or a standard rate (settings.COUNTER_LIMIT
["standard_steps_per_min"] steps of the last digit a minute), shown in the
settings and open to change; the learned rate takes its place.

"Fixed per reading" (change_limit "step") is the limit counters had before:
max_step for every reading, however long since the last one. Counters from
0.9.0 keep it unchanged; 0.9.1b1's settings are left as they are (0 stays no
limit for the fixed choices; the UI fills in the standard one when chosen).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cture's size

readings.json format 3. The rejected readings that were never answered in Review were left out,
so a sensor's checks could not be replayed in order from an export (the benchmark in
WHEEL_READER_PLAN.md phase 0 needs that). The picture's size per reading shows when a camera
came back from a restart with another size, which moves what the region shows (issue #40).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A camera that comes back with another resolution (a reboot, a changed
setting) crops differently, so the region shows something else. The
sensor now remembers the picture size its region was drawn on; when a
frame comes back another size, readings are held (problem
camera_changed), Home Assistant gets a notification, and the sensor page
asks to check the region ("The region is right" / "Adjust the region").
It reads again by itself when the size comes back.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… sensor (issue #45)

An object sensor stopped with "No such file or directory" on every check when the image
of one taught box was gone: building the taught index read every box without a cached
embedding (after a model switch, all of them) and the first missing file raised. Now a
taught box or a state sensor's training image that is missing or unreadable is left out
(logged), in the taught index, in training and in the upload suggestions.

The likely cause: training images lived in the media folder, the database that lists
them in /data. Home Assistant backs up an app's /data (also by itself before every
update) but not the media folder, so a restore brought rows back without their images.
Training images now live in <data>/samples (thumbnails in <data>/thumbs/sample, left out
of backups). Images from older versions are read where they are until the clean-up loop
copies them; the old copies stay for SAMPLES_MOVE["keep_old_days"] so the backup made
before the update still finds them, then they are removed. Files are removed only after
the row that lists them is committed. Settings -> Storage shows the free space of the
fuller of the two folders.

Tried on the test Home Assistant: the error reproduced on the old build, gone on the new
one; 136 images copied; restoring the backup from before the update and one from after
both bring every sensor back with its images.

Co-authored-by: wzd8888 <wzd8888@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A file that cannot be removed after its row was committed (in use, no permission) is
  logged instead of failing the request: the row is gone already.
- Moving training images: an image deleted before or while it is copied is skipped (and
  its new copy removed) instead of stopping the move until the next clean-up as if the
  disk were full.
- SCOPE.md: training images have no per-sensor limit; say what they are instead.
- RELEASING.md: the backup check looks for the training images too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Wheels at rest sit off their digit each their own way, which the
shared-shift decoder punishes (22 of 29 rejections were right readings);
misreads come from red wheels stopped half way. Adds the oleost benchmark
sets, a whole-digit and weakest-wheel confidence to A2, a per-wheel rest
offset to C2, two right answers for a half-way last wheel, and a first
real case for camera drift.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An ESP32 camera at 1600x1200 takes about a second per frame, so with 1 s
only the stale frame was thrown away and the frame read was often dark.
Sensors that have a light keep their stored delay; new ones get 2 s.

The wheel reader plan gets the second export's evidence: a sharp frame
read 032.776 instead of 732.776 at 0.84 because the off-digit 7 fell
outside the slack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Home Assistant's MQTT discovery refuses a sensor whose unit its device class
does not take, matched exactly: a water meter with the unit "m3" lost its
value entity without a word (only the rate and diagnostics appeared).
Discovery now writes clear spellings the way Home Assistant does ("m3" ->
"m³", "kwh" -> "kWh") and leaves the device class out for a unit it cannot
fix, with a warning in the log. Units without a device class are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The limit is there so nothing overrides it without a person: a jump over it now waits for an
answer in Review however many readings agree. A camera that moved can misread the same wrong
value over and over (issue #40), and that is no jump the agree rule could tell apart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@oleost
oleost merged commit eca2aa7 into main Oct 15, 2026
12 checks passed
@oleost
oleost deleted the promote/0.9.1 branch October 15, 2026 16:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant