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
A hardware-configuration release: set your board's serial and CAN pins from the Settings page — no more rebuilding firmware per board — plus board presets, and slider fixes.
Board pin configuration
Configurable UART (inverter serial) pins — set the RX/TX GPIOs for the ZombieVerter/OpenInverter link right in Settings, with a board-preset dropdown that fills them (Wemos + OpenInverter TX3 / RX1, ESP32 default UART0). The old TX/RX swap toggle is gone; existing devices migrate their swap setting to explicit pins automatically on upgrade.
CAN transceiver control pins — optional 5V-boost enable and transceiver enable/standby GPIOs, each with an invert checkbox, for boards that gate their CAN transceiver power or mode. Leave blank for boards that don't need them.
Board presets — pick your board and the CAN (and UART) pins fill in for you. Presets are filtered to the build's chip, so an ESP32 build only offers ESP32 boards and an ESP32-S3 build only offers S3 boards. Included:
Generic ESP32 (CAN GPIO4/5)
LilyGO T-CAN485 — CAN 26/27, 5V boost on GPIO16 (high), transceiver high-speed mode on GPIO23 (low). Verified against the board's pin_config.h.
LilyGO T-2CAN (S3) — CAN GPIO6/7
Waveshare ESP32-S3-RS485-CAN (S3) — CAN GPIO15/16
Each interface section shows which chip this build is for on its own line above the preset dropdown, so it's clear the presets are per-build.
Sliders
Negative and inverted ranges — slider tiles now accept negative min/max in any order (e.g. -10 … 10, or 0 … -10), so a slider can run into negative values or entirely below zero.
Invert checkbox — flip the slider's direction (left-to-right ↔ right-to-left) independently of the range.
Editor
Collapsible editor actions on mobile — the gauge editor's page/condition/starter controls fold into an expander on small screens (matching the Parameters action layout), leaving room to actually see the tiles you're editing.
Build targets renamed
OTA image targets are now named by chip — esp32 and esp32s3 (previously esp32_wemos / esp32_t2can).
Updating: use the Update page — the combined OTA image replaces the filesystem, so export your settings first and re-import them afterwards. The pin-configuration features need this firmware; the web UI degrades gracefully on older firmware.
A big one: parameter presets, live value streaming, a session recorder, six new gauge capabilities and a set of parameter-safety tools.
Parameter presets
Named parameter sets — capture any group of parameters with their values, name it ("Track day", "Valet", "Winter"), and apply it in one tap from the Parameters page or an Apply-preset action button on a gauges page.
Build presets from your favourites, from changed-from-default (your tune, with the RTC clock params excluded), from all current values, or one parameter at a time — every captured value stays editable.
Dry-run before apply: applying shows a diff of preset vs live values first. Values that already match are skipped (faster over the serial link), unknown parameters are flagged, and nothing is sent until you confirm. Apply is live-only; Apply & save also writes to flash.
Presets ship in the settings export bundle and have their own single-file backup/restore.
Streaming & recording
Push-based value streaming (SSE) — the firmware now streams spot values to the gauges page from a dedicated listener on port 81: one long-lived connection instead of an HTTP round-trip per sample, in both UART and CAN mode (CAN uses the same optimized SDO read path as /cmd). The browser falls back to classic polling automatically (old firmware or any connection problem), so nothing breaks. One stream at a time — a second browser gets the stream and the first quietly returns to polling.
Session recorder — a ● Record button on the gauges page captures every streamed value (across page switches), then shows a review chart and exports CSV. A zero-hardware drive logger.
Gauges
Needle dial style for radial gauges — classic pointer over the arc, value in the dial's bottom gap.
Peak-hold markers — a tick parks at the session's highest value (and lowest, on centred gauges), like an analogue peak-hold meter.
Value alarms — pair with the warn threshold: the tile pulses in the warn colour while in the zone, optionally with a beep and a browser notification. Edge-triggered, re-arms when the value drops out.
Formula tiles — compute a tile's value from spot values, e.g. udc*idc/1000 for kW, with your own unit label. Works on radial, bar, line, indicator and text tiles; abs, min, max, sqrt, round, floor, ceil, pow available.
Dual-series line tiles — plot a second value on the same chart with its own colour and live readout (heatsink + motor temperature on one tile).
Full-screen mode — one tap hides all the chrome and fills the screen with your gauges; tap ✕ (or Esc) to come back. Auto-switch pages still work.
Transparent tiles — a per-tile "Clear" option drops the card background and outline, so a gauge floats directly on the page (great for full-screen dashboards).
Swipe between pages — swipe (or click-drag) left/right anywhere on the gauge area to flip pages in view mode, with an edge-gradient hint as you drag. Reorder pages by dragging their pills in edit mode.
Parameters
Compare to file — load a parameter file in read-only mode and see exactly what differs from the inverter before touching anything; capture the differences as a new preset.
Change log — every value set through the interface (table edits, presets, gauge buttons, sliders) is recorded to a 200-entry log on the device, with timestamps, accept/reject state and CSV export.
Parameter values in the table are now always editable — no click-to-edit step.
Settings
Device nickname — name your module ("Landy", "Bench rig"); it shows in the sidebar and the browser tab, and becomes the mDNS/OTA hostname (name.local) after a reboot. Invaluable with two devices open side by side.
New Configuration sub-tab with the settings export/import plus individual backup & restore for gauge pages, presets, favourites, plot layouts and UI preferences.
WiFi secrets are labelled Passphrase and password-manager overlays are suppressed on the settings fields — no more LastPass icons floating over the SSID boxes.
Also in this release
Centre-point gauges (arc/fill pivots from a value — 0-centred power and battery-current dials in the sample set) and invertible scales carried over from the 4.21 series work, now exercised by the sample layout.
Sample layout polish: charging trace heights, phone-size radial labels, instant repaint after loading.
112 end-to-end tests (24 new this release).
Updating: use the Update page — the combined OTA image replaces the filesystem, so export your settings first and re-import them afterwards. The new firmware is required for the SSE streaming, device nickname and change-log persistence; the web UI degrades gracefully on older firmware.
Action button — a tap-to-fire tile that sets a parameter to a fixed value (with the inverter's reply checked, so rejections flash red) or sends a raw CAN frame. Confirmation before firing is on by default — these buttons write to the inverter — and can be disabled per tile.
Toggle switch — flips between an On and an Off definition: two parameter values, or two CAN payloads on one ID. In parameter mode the switch position follows the streamed value, so it shows the inverter's real state (including changes made elsewhere). Each state can be named (Enabled/Disabled, High/Low…) instead of generic ON/OFF.
Slider — drag to set a parameter anywhere between Min and Max (step from the Decimals setting). The value is sent once on release — never per pixel — and the knob follows the live value when idle.
Bar — the radial as a linear meter that fills its tile and orients itself: wider than tall reads as a level bar, taller as a column. Same ranges, gradients and decimals as the radial.
Warning thresholds
Radial and bar gauges take a Warn ≥ value with its own colour (amber default): the arc/fill and centre value switch to the warn colour at or above it. Leave blank for the previous behaviour (red past 92% of range).
Sample layout: new Controls page
Load sample layout now installs six pages — the new Controls page demonstrates every interactive type on standard values: charge-enable and BMS-balancing toggles with named states, charge-to-80%/100% and read-BMS-DTCs buttons (plus a CAN-frame example), and charge-power / regen-level sliders.
The set sticks to universal battery/motor/charging values, the Driving SOC tile is now a bar, and the Temps radials ship with warn thresholds (heatsink 80°, motor 120°, battery 45°).
Refinements
The conditional-page toggle is renamed Auto-switch (it switches pages, it doesn't create them).
Type is the first row in the gauge settings — it decides which options below apply.
A pass of phone-size fixes: action-button labels wrap onto two lines with tight padding, sliders put their value beside the track on short tiles, bar values fit narrow columns, radial min/max labels sit clear of the arc, and interactive tiles stay inside their grid squares.
For contributors
The Playwright E2E suite is at 88 tests, covering all four new tile types (including CAN paths and confirm dialogs), warn thresholds and the sample layout end to end.
The web interface now checks GitHub once a day for new releases (browser-side, using the repo this build came from — forks check their own releases). When one is newer than the running version, a badge appears in the sidebar; tapping it opens the Update tab with the release list already loaded for one-click install. Dismissable per version, and a Daily update check toggle on the Update tab turns it off entirely.
Privacy/robustness: at most one API request per day per browser, every failure (offline, rate-limited, blocked) is silent, and only a strictly version-shaped tag from the API response is ever used.
The Update page now clearly separates Inverter/VCU Firmware (the board you're driving) from Web Interface (this ESP32 module), with refreshed help text.
Sample gauge pages
Edit Layout → Load sample layout installs a five-page starter set — Driving, Battery, Temps, Charging, Debug — 66 tiles built on standard OpenInverter/ZombieVerter value names and verified against a live device: SOC/vehicle-speed/gear/derate on Driving, BMS cell stats and energy counters on Battery, pilot/cable limits and charge type on Charging, and a digital-input lamp panel on Debug.
The Charging page carries a page condition (opmode = Charge), so the sample demonstrates conditional page display out of the box. A confirmation warns before your current pages are replaced (Export settings first for a backup); values your firmware doesn't have simply read "—".
Gauges
Page conditions are now inclusive ranges: Min = Max matches exactly that value (opmode 3 to 3 means only 3 — not 4 and up), a blank bound is open-ended (Min 500 alone = "500 and above"), and Invert matches outside the range (0 to 0 inverted = "any error"). Indicator lamps gained the same Min = Max exact matching, plus an Invert option (lit while the value is OFF — e.g. trip lamps for mprot/e-stop, which read 0 when tripped).
Polish throughout: titles render at one consistent size across tile types and stay pinned to the tile top; indicator tiles keep a compact title down to phone 1×1 sizes; unit labels scale with tile size; small text tiles no longer clip their values on phones (short tiles show the unit inline); radial min/max labels sit clear of the arc; indicator dots have more air.
Settings & WiFi
The Settings page is reorganised into two sub-tabs — Device & Connection and Web Interface — with gap-free card packing, a clear segmented UART | CAN Bus picker, and Scan for devices greyed out until the saved config is actually CAN (scanning before Save could never work; editing speed/pins re-disables it until saved).
The WiFi card shows the station connection with live signal strength (bars + dBm, refreshed while the page is open) via a new /wifi-status endpoint.
New Access point only as fallback mode: the AP stops broadcasting while the station connection is up and returns automatically if it drops — and never kicks anyone currently connected through the AP. Default off (AP always on, as before).
WiFi config fields now opt out of password managers (their injected icons also landed in the wrong place).
URLs
Every view is bookmarkable: #settings/web, #gauges/Driving — and the browser back button walks tabs (handy on Android).
For contributors
The Playwright E2E suite has grown to 80 tests (update badge with an XSS guard, conditional pages, sample layout, settings scan gating, WiFi status), still fully hardware-free against the mock ESP.
This commit was created on GitHub.com and signed with GitHub’s verified signature.
What's new in v4.19
UART reliability: no more rebooting the ESP
Wrong-baud junk no longer breaks negotiation: the inverter's line buffer is resynchronised before every probe, so replies can't get offset and strand the ESP at the wrong baud rate.
An inverter reboot under a fast ESP now self-heals: the very next command detects the silence, drops back to 115200, resyncs and retries — you get your data immediately, and the link returns to fast speed on the following command.
Negotiation is bounded and polite: at most 3 attempts per boot, re-armed only once slow comms prove alive — so a rebooting or absent inverter is never blasted with probe traffic (which could previously knock the inverter's own console offline). Reboot Inverter and firmware updates reset the budget.
Conditional page display (gauges)
Each gauge page can carry a condition — a value plus Min/Max (and optional invert), switching at the midpoint exactly like an indicator. When the condition starts matching, the app switches to that page automatically: e.g. jump to a Debug page while lasterr is non-zero, or a Charging page when opmode says so.
A persisting match won't yank the page back, so you can still browse freely; if nothing matches, the current page stays put. The first page (in pill order) whose condition matches wins.
An Auto pages toggle above the grid arms/disarms the feature; conditions and the toggle live in the device layout and ride Export/Import settings.
Bookmarkable URLs
Every tab now has a URL breadcrumb (#gauges, #parameters, …) and gauge pages nest inside it (#gauges/Driving) — so a browser favourite or home-screen shortcut can open a specific inverter view directly.
The browser back button walks tabs (handy on Android); flipping gauge pages doesn't pollute history.
Gauges editor improvements
10-column grid (was 12): comparatively bigger tiles on a phone, same layout everywhere.
Tap to configure: in edit mode, tap any tile for its settings — no more overlay buttons overlapping on tiny tiles — plus a Duplicate button to clone a fully configured tile.
New Text tile type: shows a live value as large text, or a static caption for labelling dashboard sections.
Custom labels on any gauge (replaces the value name), and decimal places are configurable per gauge.
Invertible indicators: a new Invert option lights the lamp while the value is off/below the switching point (e.g. "brake released"); the caption still names the value's real state.
Bigger (18 px) resize grip; 1×1 tiles hide it and resize from their settings instead.
Bug fixes: full-codebase audit (30 fixes)
A complete audit of the firmware and web UI, every finding fixed and regression-tested:
Web UI: parameter edits rejected by the inverter (out of range, unknown) are now reported instead of silently counted as applied; firmware-update and OTA flows can't get stuck on transient errors; download stall detection; high-rate polling races fixed (favourites streaming, plot sampling, modal edits no longer reverted by stream ticks).
Firmware: concurrent CAN endpoint calls are rejected cleanly (409) instead of corrupting state; can_nodes parsing is string-safe; RTC handling validates its input; upload/OTA guards against double-starts and rollback on task-spawn failure; SD logging closes files on delete-all; input validation on pins, AP names and repeat counts; several buffer-bounds fixes in UART parsing.
For contributors
The Playwright E2E suite has grown from 49 to 67 tests (gauges editor, routing/deep links, conditional pages, parameter file uploads, UART/CAN update flows), still running against the mock ESP with a simulated inverter — npm run mock needs no hardware.
The Gauges tab is now a full dashboard editor: tiles live on a grid and are freely dragged and resized in Edit Layout (works with touch on mobile). Gauges rescale live while you drag, dials stay square, and line gauges can be any shape — long and flat included.
Multiple named pages (e.g. Driving, Performance, Debug), each with its own layout — page pills above the grid, create/rename/delete in the editor.
Per-tile settings: tap a tile's ⚙ in edit mode to set its value, type, colour and range — no more matching tiles to a side list.
New Indicator gauge type: a lamp for On/Off and 0/1 values, lit in your chosen colour when the value passes the midpoint between Min and Max. Works with enum values (shows "Off"/"Run" style labels) and sizes down to 1×1.
Line gauges have configurable history length and sample rate (Points × Sample = time window), so a tile can show the last few seconds or the last several minutes.
Existing gauge layouts migrate automatically, and everything is included in Export/Import settings.
Dashboard & Settings
Choose your dashboard values: a new Settings tile picks up to 5 spot values for the dashboard hero card (enum values resolve to their labels; sparklines included).
Theme, accent colour and dashboard value choices now live on the device, so your setup follows the inverter across browsers and is restored by Import settings.
Settings tiles reorganised: Appearance & Display (with the keep-awake switch restyled) and Data Interface.
CAN (community contribution)
CAN node IDs up to 127 (was 32) throughout firmware and UI, an ENABLE_SDCARD build flag for boards without SD, and the web interface is now reachable in station (STA) WiFi mode. Thanks @Modellfan! (#2)
For contributors
New CI test suite gates every pull request: ESLint, asset-sync checks, and a 49-test Playwright E2E suite that drives the real UI against a mock ESP + simulated inverter. npm run mock serves the interface with no hardware for development. See CONTRIBUTING.md.
Load parameters from file previously only stored the JSON on the device and never applied it, so a saved parameter set was effectively ignored. It now reads the file and writes each value to the inverter, so the set is properly restored. Works in both UART and CAN modes.
Accepts both the exported format (from Download parameters file) and a flat name→value map.
A progress bar — the same one the firmware update uses — shows each parameter being applied, since every write is a serial round-trip. A confirmation prompt appears before applying, and a summary (including any parameters that failed) when it finishes.
The values are applied live, so use Save parameters to flash afterwards to keep them across a reboot.
Android file picker
Fixed .json files being greyed out and unselectable in the file picker on Android, for both Load parameters from file and Import settings. The restrictive file-type filter was removed; the file contents are validated after selection instead.
New Settings → Keep screen awake toggle that stops the device's screen sleeping while the interface is open. Uses the Screen Wake Lock API where available and falls back to a hidden looping video (NoSleep.js) so it also works over the ESP's plain HTTP. The setting persists and is included in Export settings.
Terminal (Command console) reliability & UX
No more lost responses. Sending a command pauses the background JSON refresh for its duration, so the two can't fight over the single UART link.
Commands are echoed with a > prompt, and an empty reply prints (no response) instead of a blank line.
Failures are visible: errors and a 15-second timeout (for a hung connection) print to the terminal instead of silently vanishing.
A CMD badge shows while a command is in flight (instead of the misleading FAST).
Fixed the command-output box overflowing the screen on a large json dump.
Housekeeping
Added THIRD_PARTY_NOTICES.md documenting all bundled libraries and their licenses.
Spot Values favourites stopped updating at the FAST refresh rate. With the refresh rate set to FAST (max speed), favouriting a value and viewing favourites-only would freeze the live values (and make the UI sluggish). The fast poll loop was busy-spinning while paused, starving the favourites stream. It now yields correctly, so favourites update smoothly at any refresh rate.
Everything else from v4.14 is unchanged — over-the-air updates from the Update tab (combined *-ota.bin images, from a GitHub release or an uploaded file), the esp32_wemos / esp32_t2can build targets, and the Export-settings backup button.
Update the whole web interface over WiFi from the Update tab — no cables, no toolchain. Updates use a combined *-ota.bin image that flashes the ESP32 firmware and the UI together, so the two can never drift out of sync.
Update from GitHub — press Get releases, pick a release, and the image matching your board is auto-selected (any can be chosen manually). Then Download & install. The repository field defaults to the repo this build came from.
Install OTA image from file — flash an *-ota.bin you built or downloaded yourself. Uploaded files are checked for the *-ota.bin name, with a warning if the image is for a different board.
The bootloader and partition table are never touched, so a bad image stays recoverable over USB. The device reboots and the page reloads automatically.
Build targets and image names
Build targets and release images renamed to esp32_wemos (classic ESP32 / Wemos) and esp32_t2can (LILYGO T-2Can, ESP32-S3).
Each release now ships two images per board: *-0x000.bin (full-flash, for a blank board at offset 0x0) and *-ota.bin (combined OTA, for in-browser updates).
Other changes
Browser tab title is now OI Web Interface.
Build now auto-regenerates the gzipped web assets, so they can't go stale.
Cleaned up legacy esp8266 references and refreshed the PlatformIO / Arduino IDE docs.
Mobile layout and tooltip fixes (tooltip clipping, Spot Values spacing, Update-tab alignment).