Repository navigation
v2.10.0 — telemetry no longer loses records when the clock goes back, and accounts apply without a restart
Telemetry no longer loses records when the clock goes back, and saving accounts no longer restarts the device. The configuration page's dry run no longer changes the running device, a restore cut off halfway keeps the files it finished, and an alarm limit that is not a number is refused instead of becoming 0.
This is the second signed release: a device on v2.9.0 checks its signature before installing it. CONFIG_VERSION stays at 26: the configuration file is the same, and v2.9.0 reads it. Most of this release answers the outside review of v2.7.3 (docs/analysis/PLANO_REVISAO_EXTERNA.md).
Telemetry sends a record by where it was written (#232)
The telemetry cursor was one timestamp: a record went out when it was newer than the newest one sent. A block written after another but stamped before it was never sent, while the page showed nothing pending. A clock that goes back leaves exactly that: the boot's provisional clock corrected by NTP, or a clock set by hand. On the bench it lost 6 of 75,778 records on 2026-09-21, and 1 of 13,671 in an Air's drain.
The cursor is now a write position in each day file. When a position cannot be trusted, the whole day file goes again, logged as code 554: duplicates, never a gap. With the clock 40 minutes ahead and then put back, the code before this release sent none of the 7 records written after the change; this release sent all 7. A send in steady state costs 89 ms instead of 69, and about 400 B of heap.
Accounts and sessions (#229, #230)
- Saving accounts no longer restarts the device. Each save used to cost a restart of about 25 s. Accounts now apply at once, and Apply now shows each new account's one-time password.
- A web session ends with its account. That covers a deleted account, a slot that now holds another name, and a password someone else set. Otherwise the session acts with the permissions the account holds now.
- A name with no account costs the same check as a wrong password: 5,000 rounds. The time of the answer no longer tells which names exist, at
/api/loginor at/metrics.
Fixes
- The configuration page's dry run (
_dry=1) no longer changes the running device (#234). The page sends it after every staged edit. Staging the mute muted the device, and staging a time zone applied it. The history interval, NTP, syslog, Home Assistant Discovery, the DNS fields and the persistent connections were written into the live configuration. - An alarm limit that is not a number is not 0 (#235). Until now,
null,"abc"andtruebecame 0 and the reply was 200. Nownullkeeps the stored bound, and anything else is refused. - A restore that fails halfway keeps the files it finished (#236). It used to delete them all, and the device booted on factory settings. The apply now takes only the backup the last validate passed; any other gets 409 with status 11. The 200-file limit is gone.
The panel and the web pages (#227, #237, #239)
- The panel's Settings menu goes in order of use: day to day, access, the screen, then License. Date and time is row 4. Configuration Mode, which opens the setup access point, is row 8.
- The Files page has a text viewer:
- JSON is indented, and its objects and arrays fold;
- language packs, themes and INI files fold by section;
- every line is numbered, and files up to 64 KiB open;
- Original shows the text as it is.
- The telemetry page's Live Previews are built from this device: its name, MAC and serial, its readings, its alarm limits and the session's account. They show two measurement records, one with a sensor in failure, and one record of each of the ten alarm codes, in the formats the firmware sends.
Measured on the bench
The release gate of AGENTS.md §2 ran on the candidate the CI signed on main (run 37132567925). It ran on the bench board (touch display, two DS18B20, two DHT22, a BMP280), from the published v2.9.0 with the bench's configuration. The images attached here carry the same image bytes; their signature is their own, because every signing run makes a new one.
- Update from v2.9.0 over the air (port 8080), on release, Air and alpha:
2.10.0installed, five sensors reading;- every configuration value the web API reports unchanged, and the configuration file identical byte for byte;
- the
.bkpback with 69 or 70 of 74 files identical. The others are the log, the history and the telemetry cursor. - The Air's own options, which an update erases, came back with the
.bkp.
- The candidate over itself, checking its own signature (
v0), on all three: the same. - Back to v2.9.0 and up again, over the air:
v0 both ways, the configuration unchanged. - Refused, with the configuration intact before and after a reset: unsigned (8), the Air's signed image (7), and the candidate with one byte changed (9).
- Upload cut at 400 kB, then a reset, with and without the filesystem filled in between: configuration intact.
- 30 minutes without a restart.
- Web suite on the test image: 87 passed, 0 failed.
- The alpha's LCD, on an HD44780: every step of an update, the three refusals by name, the cut upload, and the access point's pages.
Flash
Signed .bin sizes against the published v2.9.0:
| Image | v2.9.0 | v2.10.0 | Slack under the 1,040,384 B ceiling |
|---|---|---|---|
| release | 1,025,949 B | 1,032,645 B | 7,739 B |
| alpha | 982,429 B | 990,621 B | 49,763 B |
| Air | 1,027,389 B | 1,031,485 B | 8,899 B |
The ceiling is for updates over the air.
Upgrading
-
From v2.9.0: over the air, from the Files page, with the
.binattached here. The configuration and the telemetry cursor carry over by themselves. -
Back to v2.9.0: over the air with v2.9.0's
.bin(both carry security version 1; checked on the bench), or over USB. The configuration stays, and v2.9.0 reads the cursor this release writes. -
From v2.8.x or older: read the Upgrading notes of v2.9.0 first.
-
Restoring a backup from simut-rx's fleet manager needs v1.9.1 or later. The apply now needs a validate of the same backup first.
-
Scripts that call the API:
POST /api/restore?op=applyhas to follow?op=validateof the same backup, or it gets 409 with status 11;- an alarm limit that is not a number is refused;
_dry=1acceptsusers;- a try (
_nosave=1) of the fields listed under #234 is refused with 409.
docs/API_POST.mdhas the details. -
Settings menu: v2.9.0's notes name Settings → 12 for the access point and Settings → 13 for the date and time. They are rows 8 and 4 now.
-
Language packs: upload the two attached here on the Files page, then reboot. With the v2.9.0 packs everything works, and the new strings read in English.
Known, and not fixed here
- A chunked reply occasionally loses its framing (#189): 0.15–0.6 % of
/api/statusreads in a tight loop. On the bench it also broke one of nine backup downloads before an update; the page then stops before the upload. - On the alpha, saving the configuration can restart the device through the watchdog. The save does not park Core 1, which keeps drawing the LCD from the flash being written. This affects every alpha since its first build. It was seen once on the bench, and the configuration came back intact. A fix follows.
- On the alpha, the log's messages in pt-BR or es-ES come out empty, by the code.
- Accented lines on the boot screen print
?, by the code. - The web page does not retry an install refused with 503, by the code. A touch on the panel in the 5 s before the install causes that refusal. The restart that follows discards the staged image.
configure terminaldoes not needenable, although the command table says it does.- A try (
_nosave=1) of a stricter PIN policy applies it without marking the PINs below it for a change, by the code. - With two pressure sensors, the measurement line sends the pressure under the first one's key and with the last one's value, by the code.
- The Telemetry page's token list for the alarm line stops at v22. Chapter 22 of the manual lists every token.
Full notes: CHANGELOG.md.