Releases: Techposts/TankSync
TankSync Transmitter v3.3.0 — deep-sleep current fix (~15x lower standby)
This release fixes the transmitter's deep-sleep power draw, taking standby from
~3 mA down to the chip's floor and turning a ~1-2 week unaided runtime into
multi-month battery life.
What was wrong
- On the ESP32-C3, gpio_deep_sleep_hold_en() keeps the RTC_PERIPH power domain
powered so it can latch GPIO states through sleep — and that domain draws
~2.4 mA continuously. The TX paid that tax the entire time it slept.
The fix
- Drop the deep-sleep GPIO hold entirely. The gates are driven to their OFF
level before sleep; the board's external gate pull-resistors hold the FETs off
once the pads isolate, so loads stay cut without the costly hold. - The wake-side hold-release is kept, so a unit updating from older
(hold-using) firmware cleanly releases any latched holds on its first wake. - Power down the USB-Serial-JTAG PHY before sleep (small extra saving).
Measured
- Deep sleep: ~2.42 mA with the old hold, ~47 uA without it. Whole transmitter
board ~190 uA (the always-on INA219 fuel-gauge + boost idle set that floor). - Overnight soak: both bench tanks stayed online ~17 h with zero faults and the
battery held flat — confirming the drain in practice, not just on a meter.
Battery life now scales with the reporting interval: roughly 2-2.5 months at the
300 s default on a 2900 mAh cell, ~4-6 months at 600-900 s, and effectively
indefinite with modest solar.
Also in this build
- LD2413 24 GHz radar level-sensor driver now reading on hardware (alternative
to the ultrasonic; select per-TX with SENSOR=ld2413).
Pairs with rx-v3.3.0. Update via the TX's WiFi-AP OTA (hold BOOT to enter update
mode) or re-flash over USB.
Downloads (every variant for this firmware version)
…-transmitter-<tag>.bin— Transmitter, LoRa (RYLR998 module)…-transmitter-lite-<tag>.bin— Transmitter, Lite / ESP-NOW (built-in radio, no module)…-receiver-<tag>.bin— Hub, ESP32 DevKit…-receiver-s3-<tag>.bin— Hub, ESP32-S3 SuperMini
Only the variants for this firmware are present. Flash at 0x10000 with esptool, or use the one-click browser flasher.
tx-v3.2.0 — LoRa MAC-echo + 5-minute default sleep
- LoRa MAC-echo: each TANK packet is stamped with the transmitter's MAC so the
hub can reject spoofed addresses. Backward compatible — older hubs simply
ignore the extra field. - Default sleep interval is 5 minutes for longer battery life; adjust it per
tank from the hub or the PWA.
Downloads (every variant for this firmware version)
…-transmitter-<tag>.bin— Transmitter, LoRa (RYLR998 module)…-transmitter-lite-<tag>.bin— Transmitter, Lite / ESP-NOW (built-in radio, no module)…-receiver-<tag>.bin— Hub, ESP32 DevKit…-receiver-s3-<tag>.bin— Hub, ESP32-S3 SuperMini
Only the variants for this firmware are present. Flash at 0x10000 with esptool, or use the one-click browser flasher.
rx-v3.3.0 — Hub holds bad readings instead of alarming on them + Wi-Fi setup scan fix
This Hub release makes tank readings more trustworthy and smooths out
first-time Wi-Fi setup.
Ultrasonic and radar level sensors occasionally throw a single wild
reading — condensation on the sensor face, a splash, or a multipath echo
can make a tank look like it jumped 15–20% in one wake. Until now that
glitch could flash on the dashboard and even trigger a false low-water or
overflow alert.
The Hub now watches the rate of change between readings. A jump too fast
to be real water movement (faster than about 1.5%/min, and at least 6% in
one step) is held back: the Hub keeps showing the last confirmed level and
waits for the next reading to decide. If the level snapped back it was a
spike and is discarded; if it stayed changed it's real and is accepted — so
genuine fast fills and heavy draws still track correctly, just one reading
later. The raw reading is always recorded for diagnostics, and alerts are
suppressed while a reading is held so you never get a phantom alarm.
The app shows a small "reading held" note on a tank while this is happening,
and the cloud applies the same check as a second layer of defence.
During first-time setup the Hub's configuration page sometimes showed an
empty Wi-Fi network list, forcing you to type your network name by hand.
The Hub now runs its access point and Wi-Fi scan at the same time, so nearby
networks reliably show up in the picker.
Open the TankSync app → your Hub → OTA Update, or use the Hub's local web
page. Your paired tanks, names, and settings are preserved across the update.
Downloads (every variant for this firmware version)
…-transmitter-<tag>.bin— Transmitter, LoRa (RYLR998 module)…-transmitter-lite-<tag>.bin— Transmitter, Lite / ESP-NOW (built-in radio, no module)…-receiver-<tag>.bin— Hub, ESP32 DevKit…-receiver-s3-<tag>.bin— Hub, ESP32-S3 SuperMini
Only the variants for this firmware are present. Flash at 0x10000 with esptool, or use the one-click browser flasher.
rx-v3.2.1 — Smart Switch lives in the cloud properly
Smart Switch fixes and full cloud sync, building on 3.2.0:
- A switch's telemetry now republishes to the cloud on every report (5s),
so the app shows it live instead of "waiting for the switch to report"
minutes after the last hub restart. - The pump rule and electrical settings publish to the cloud, and three new
remote commands (rename, rule, settings) let the TankSync app edit them
from anywhere — same validation as the hub's own web UI. - A switch paired from now on gets a unique default name derived from its
hardware address (e.g. "Smart Switch A3F2") instead of "Smart Switch 1". - Renaming a switch in the hub web UI now edits inline — the old dialog was
silently blocked in installed-app browsers. - Physical button presses on the switch are adopted as a manual hold, so a
hand-toggled pump no longer flips back ten seconds later. - Unpairing a switch now tells the switch to forget the hub too (relay off,
pairing cleared), and it waits for a deliberate button hold to re-pair. - New switch settings panel: mains voltage, over-current trip, dry-run
floor — pushed to the switch and persisted.
Pairs with switch firmware ss-v0.1.2. TX firmware unchanged (tx-v3.2.0).
Downloads (every variant for this firmware version)
…-transmitter-<tag>.bin— Transmitter, LoRa (RYLR998 module)…-transmitter-lite-<tag>.bin— Transmitter, Lite / ESP-NOW (built-in radio, no module)…-receiver-<tag>.bin— Hub, ESP32 DevKit…-receiver-s3-<tag>.bin— Hub, ESP32-S3 SuperMini
Only the variants for this firmware are present. Flash at 0x10000 with esptool, or use the one-click browser flasher.
rx-v3.2.0 — SmartGhar Smart Switch support + LoRa MAC-echo
This hub release adds full support for the SmartGhar Smart Switch — a mains
relay that controls a water pump automatically by tank level.
Smart Switch
- Pair a Smart Switch to the hub (Devices → Pair new); it appears under the new
Switches tab, never as a tank. - Level-based pump automation runs on the hub: start/stop thresholds, an
optional source-tank guard, and motor-protection guards — a minimum
hysteresis band, minimum rest between runs, a dry-run lockout, and a runtime
failsafe that the hub keeps longer than its intended run so the pump never
flap-cycles. - Switch telemetry (relay, current, power, temperature, faults) bridges to the
PWA and to Home Assistant; you can toggle the pump from either.
Security
- LoRa MAC-echo: the hub drops any packet whose stamped MAC doesn't match the
registered device, so a spoofed address can't inject readings.
Other
- Switches are kept out of the tank dashboard, the device list, and the Home
Assistant tank entities, so they only ever appear as switches.
Flash over Wi-Fi from the hub's web UI, or with the browser flasher.
Downloads (every variant for this firmware version)
…-transmitter-<tag>.bin— Transmitter, LoRa (RYLR998 module)…-transmitter-lite-<tag>.bin— Transmitter, Lite / ESP-NOW (built-in radio, no module)…-receiver-<tag>.bin— Hub, ESP32 DevKit…-receiver-s3-<tag>.bin— Hub, ESP32-S3 SuperMini
Only the variants for this firmware are present. Flash at 0x10000 with esptool, or use the one-click browser flasher.
TankSync Transmitter 3.0.0 — new ESP-NOW "Lite" variant
Introduces the Lite transmitter: the same TankSync experience without the LoRa module, using the ESP32-C3's built-in radio for same-building range.
What's new
- ESP-NOW "Lite" transport variant via a build-time
transport_iface(-DTRANSPORT=lora|espnow). One source tree, two binaries — no module on the Lite board. - Full parity with LoRa. Lite keeps auto-pair, config push, remote OTA, and an identical
tx_data_t, so the dashboard / Home Assistant / PWA see no difference beyond range. - Pairs to the universal hub (rx-v3.0.0+); the hub auto-detects transport at pair time.
Downloads
tanksync-transmitter-tx-v3.0.0.bin— Transmitter, LoRa (RYLR998 module)tanksync-transmitter-lite-tx-v3.0.0.bin— Transmitter, Lite / ESP-NOW (built-in radio, no module)
Verified on hardware
- ESP-NOW transmitter validated end-to-end against ESP32 DevKit and ESP32-S3 hubs; mixed fleet confirmed.
Requires
- A hub on rx-v3.0.0 or newer for ESP-NOW pairing.
Who should install
- LoRa users: optional. New Lite SKU: flash the
-litebinary.
Full Changelog: tx-v2.0.15...tx-v3.0.0
TankSync Hub 3.0.0 — universal LoRa + ESP-NOW hub, redesigned display
The hub now serves LoRa and the new ESP-NOW "Lite" transmitters at the same time, and ships a fully redesigned OLED + LED experience. Recommended for every hub; required to pair the new Lite transmitters.
What's new
- Universal hub. A concurrent ESP-NOW receive path runs alongside LoRa and fills the same registry — one hub handles a mixed LoRa + Lite fleet. Transport is auto-detected at pairing; there is no selector to set.
- Redesigned OLED. Per-tank layout: name + signal bars, a cylinder with wavy water and level ticks, droplet + litres, and battery + last-update. Cloud-optional fix — no more stuck "NOT LINKED" when running without the cloud.
- WS2812 LED ring. Boot animation, gauge that follows the OLED's current tank (8- and 24-LED modes), live strip-mode switching, and a WiFi LED that turns green when connected.
- ESP32-S3 SuperMini pin-map updates for the S3 hub build.
Downloads
tanksync-receiver-rx-v3.0.0.bin— Hub, ESP32 DevKittanksync-receiver-s3-rx-v3.0.0.bin— Hub, ESP32-S3 SuperMini
Verified on hardware
- ESP-NOW validated end-to-end on ESP32 DevKit and ESP32-S3 hubs; mixed LoRa + Lite fleet confirmed. OLED + LED redesign validated on S3.
Who should install
- All hubs (optional but recommended). Required if you are pairing ESP-NOW "Lite" transmitters.
Full Changelog: rx-v2.8.6...rx-v3.0.0
rx-v2.8.6
rx-v2.8.6 — bidirectional sensor sync + on-device diagnostic console
This release pairs with tx-v2.0.15 and lights up two things I've wanted on the hub for a while: the receiver now understands which sensor each transmitter is actually running, and there's a built-in diagnostic console you can pull straight from the device — no laptop-on-balcony required.
What's new
Per-transmitter sensor selector
Each tank's edit sheet now has a Sensor dropdown (Ultrasonic AJ-SR04M / mmWave HLK-LD2413). The receiver tracks two fields per TX:
sensor_kind— what the hub wants the TX to useactive_sensor— what the TX is actually running, reported back inside each TANK packet
When you save a change from the hub or the PWA, the value gets queued as a remote-config update, sent over LoRa via the existing SET: downlink (now with a :SENSOR= clause), ACKed by the TX, and the next TANK frame closes the loop with active_sensor matching sensor_kind. Mixed-firmware fleets keep working — older TXs that don't yet emit the field parse fine with active_sensor="".
If you change the sensor on the TX directly (via its AP web UI), the hub also learns from it. When the registry sees an active_sensor that diverges from its sensor_kind and no SET is in flight, it auto-syncs the registry to TX-truth. So edits from either side converge.
Diagnostic console
Boot-time logging is now captured into a 4 KB ring buffer inside the receiver and exposed at GET /api/logs. Paired with the diagnostic-mode toggle on the TX firmware, you can pull a live log tail from either device to a terminal:
curl http://<hub-ip>/api/logs # whole tail
curl http://<hub-ip>/api/log_clear # wipe + start freshNo serial cable, no rooftop, no opening the case. The previous LoRa-OTA debug story relied on plugging into the TX — now you can diagnose from anywhere on the LAN.
MQTT bridge for the new field
Cloud telemetry now exposes:
tank_<addr>/sensor_kind(retained) — hub's desired sensor for this TXtank_<addr>/active_sensor(retained) — what the TX is currently runningcmd/set_confignow accepts asensor_kindfield for remote control from the PWA
What changed (file-level)
components/transmitter_registry/— addedsensor_kind+active_sensorfields, bidirectional auto-sync when TX-truth diverges from registry intent,registry_set_sensor_kind()APIcomponents/lora_rylr998/— TANK parser extracts the 11th positional field (active_sensor); backwards-compat with older TXs that omit itcomponents/web_server/— Edit Tank sheet adds the Sensor dropdown (full-width row),/api/transmittersreturns both fields,/api/logs+/api/log_clearadded, max URI handlers bumped to 12 so the new endpoints actually registercomponents/mqtt_client/— publishes both fields as retained topics, acceptssensor_kindoncmd/set_configcomponents/log_buffer/— new component: 4 KB ring buffer wired up viaesp_log_set_vprintf()main/main.c— SET-frame builder appends:SENSOR=...when a sensor change is queued;log_buffer_init()runs first thing inapp_main
OTA + upgrade notes
Standard OTA from any rx-v2.7.x+ build via the Settings → System → Check for updates flow on the hub web UI. The cloud-side OTA proxy and PWA OTA panel both already understand the new version. No manual steps required after upgrade — the new fields default to empty ("") on existing transmitters and populate as soon as each TX reports its active_sensor on the next wake.
If you're also flashing tx-v2.0.15 transmitters: the pair works end-to-end on the bench (Normal Water Tank, addr 2, on my own deployment). For mixed fleets with older TX firmware, the hub gracefully treats them as active_sensor="" and skips sensor-change downlinks until you upgrade them.
Why rx-v2.8.6 instead of rx-v2.8.5?
rx-v2.8.5 already shipped earlier this week as the version-stamping bugfix release (single-VERSION-file pattern). The sensor-sync work outgrew that scope, so it gets its own tag to keep release-history clean. Both 2.8.5 and 2.8.6 are OTA-compatible with any tx-v2.0.x transmitter.
Hardware compatibility
No hardware changes. Works on existing TankSync REV 2.2 PCBs and breadboards. The HLK-LD2413 driver lives on the TX firmware side, not the RX — see the tx-v2.0.15 notes for sensor wiring.
— Ravi
tx-v2.0.13
tx-v2.0.13 — version stamping fixed (paired with rx-v2.8.5)
Companion release to rx-v2.8.5. Same single-VERSION-file pattern applied on the transmitter side.
What's fixed
esp_app_desc.versionnow reflects what was actually built. Like RX, the TX binary was stamping its version field from a hardcoded literal infirmware/Transmitter-IDF/CMakeLists.txt. Released TX binaries since tx-v2.0.11 all carried a stale version string in the binary (offset 0x30), even though the code itself was current. The PWA's Devices page, hub's web UI Firmware tab, MQTT-publishedtx_versionfield — all read the wrong value.- After this build the TX correctly self-reports
2.0.13.
Internal
- Single source of truth: edit
firmware/Transmitter-IDF/VERSION(one file). CMake reads it, setsPROJECT_VER, andconfigure_file()generatescomponents/tanksync_version/include/version_gen.hconsumed bymain/,components/wifi_ota/, andcomponents/lora_tx/. - Build provenance fingerprint preserved in
main/main.c(the magic constant + the unique typo log string incomponents/lora_tx/lora_tx.care unchanged). - No protocol changes — packet format identical to tx-v2.0.12.
Upgrade
- PWA: Settings → Firmware → expand each TX → "Update available · v2.0.13" → tap. Hub orchestrates the over-Wi-Fi OTA; TX wakes up and pulls the new binary.
- Browser flasher: tanksync.smartghar.org/firmware → Transmitter card → Install.
- Manual:
esptool.py --chip esp32c3 -b 460800 \ write_flash 0x10000 tanksync-transmitter-tx-v2.0.13.bin
Compatibility
- Hub firmware: any
rx-v2.7.xorrx-v2.8.xworks (no protocol bump). - PWA: any version (no UI dependency).
- HACS: any version (no entity-shape change).
Verification
After flashing, confirm the TX self-reports 2.0.13:
# Direct inspection of the .bin
xxd -s 0x30 -l 32 tanksync-transmitter-tx-v2.0.13.bin
# Should print: 2.0.13 followed by null padding
# Or check at runtime: hub web UI → Devices → TX row → version columnPaired with
- rx-v2.8.5 — see for the matching RX-side notes.
rx-v2.8.5
rx-v2.8.5 — version stamping fixed (single-VERSION-file pattern)
This is the first per-binary public Release of TankSync under the rx-v* / tx-v* / rxc3-v* tag scheme. See the Firmware Versions wiki page for release history + compatibility matrix.
Paired with: tx-v2.0.13 — same version-stamping fix on the transmitter side.
What's fixed
esp_app_desc.versionnow reflects what was actually built. Every release since rx-v2.7.13 shipped with the version string stuck at"2.7.13"becausefirmware/Receiver-ESP32-DevKit/CMakeLists.txthardcodedPROJECT_VER. The OLED, web UI footer, PWA Firmware page, MQTTfirmware_versionfield — all reported the wrong version even though the underlying code was current.- Bench-confirmed: the hub at
192.168.0.56was reportingv2.7.13while running rx-v2.8.4 features. After flashing this build it correctly reportsv2.8.5.
Internal
- Single source of truth: edit
firmware/Receiver-ESP32-DevKit/VERSION(one file). CMake reads it, setsPROJECT_VER, andconfigure_file()generatescomponents/tanksync_version/include/version_gen.hconsumed bymain/,components/web_server/,components/ota_manager/, andcomponents/wifi_manager/. - Build provenance fingerprint preserved in
main/main.c(planted earlier in the rx-v2.7.x line). - No protocol changes — fully backward-compatible with any
tx-v2.0.xfirmware.
Upgrade
- PWA: Settings → Firmware → "Check for updates" → Install.
- Browser flasher: tanksync.smartghar.org/firmware (one click, no toolchain).
- Manual:
esptool.py --chip esp32 -b 460800 \ write_flash 0x10000 tanksync-receiver-rx-v2.8.5.bin
Compatibility
- PWA ≥ 1.14.0 (already shipped)
- HACS ≥ 0.8.0 if using buzzer entities
- TX firmware: any
tx-v2.0.xworks
Verification
After flashing, confirm the binary self-reports 2.8.5:
# Direct inspection of the .bin
xxd -s 0x30 -l 32 tanksync-receiver-rx-v2.8.5.bin
# Should print: 2.8.5 followed by null padding
# Or check at runtime
curl http://<hub-ip>/api/system | grep version
# Should show: "version":"2.8.5"