Skip to content

v3.8.0 — 2026-07-14

Choose a tag to compare

@avandeputte avandeputte released this 14 Jul 21:53
· 17 commits to main since this release

Everything since v3.4, summarised. One client can now drive any wall: a new GET /api/capabilities tells it exactly what a wall can show, and a new POST /api/display/cells sets a whole row through the same contract the Matrix Portal Gateway answers — so the companion drives the physical wall and the LED-matrix emulation identically. Plus quiet-time blanking, a per-board MQTT identity, safer web OTA, and a security fix.

Upgrading from v3.4: if you use the Home Assistant integration the device id changes (see Fixed) — delete the old device. Modules re-report their flap set to the gateway over the first couple of minutes after boot (persistence format bumped); nothing you need to do.

Added

  • GET /api/capabilities — what characters the wall can show. Every module owns its reel, so the response reports union (any module), common (every module — these differ on a mixed wall), and sets: each distinct reel once, with the module ids that carry it ("0-44,50"). Colour flaps are listed by name; modules too old to report a reel are assumed, ones not yet known are unknown. The Matrix Portal Gateway answers this URL identically. The gateway learns each module's flap set from the v31+ A reply and persists it (asking a 45-module wall costs ~90 s of bus time), filled by a background trickle and re-read only when an N changes a reel.
  • POST /api/display/cells — set a run of modules in one call: {ch | color | blank | skip} per cell, named colours, step_ms cascade pacing. The same JSON contract the Matrix gateway answers. Lenient — a cell this wall cannot show is skipped, not a 400 that discards the row (the response reports sent vs skipped); only structural errors 400.

Changed

  • The dashboard speaks 13 languages plus English, chosen from the browser, with a Settings override and ?lang=, all in one image.
  • Quiet Time now blanks the wall — entering quiet homes every reel (the Home All operation), leaving it restores what was showing (or the newest request made while quiet). Schedule, manual switch, REST, MQTT and Home Assistant alike.
  • The Home Assistant re-skin is complete — every control clears WCAG AA in both themes, and the module cards, status tiles and bus monitor read the palette tokens too.

Fixed

  • [Security] A remotely-reachable stack buffer overflow is closed. The by-serial flap-config path (POST /api/flap/flapconfig with an sn, and the MQTT flapconfig topic) built its RS-485 frame from an unvalidated serial into a fixed stack buffer, so a long serial overran it. The serial is now validated before use.
  • Every gateway now has its own MQTT identity. The client id and HA device id were derived from a MAC field identical on every ESP32, so two boards on one broker evicted each other in a loop. They now use the bytes that actually differ. The HA device id changes — delete the old device.
  • Web OTA no longer reboots the board mid-flash. A low-heap watchdog fired during an upload (which drives heap low on purpose) and reset onto the old image; it now stands down for the duration of an upload. (Browser OTA on this 16 MB board remains heap-tight near the end of a large image; ArduinoOTA/espota is the reliable path.)
  • Smaller fixes: the companion-URL save no longer contends with a firmware upload for the flash; /api/capabilities returns in ~0.03 s (buffered, scratch in PSRAM) and its module-id range list can no longer truncate or mis-order; and the double-quote flap is reachable by character (" maps to the reel's q).

Board: Waveshare ESP32-S3-RS485-CAN (16 MB flash). Flash SplitFlapGateway-3.8.0.bin at offset 0x10000, or use the dashboard's OTA upload / espota.