New post-build script pio-tools/timestamp-firmware.py copies firmware
artifacts to timestamped filenames when append_timestamp = 1 is set in
the [tasmota] section of platformio_override.ini. Default off; standard
builds unaffected.
The timestamp is extracted from the ELF symbol table via nm: named PROGMEM
symbols mdate_P and mtime_P in GetBuildDateAndTime() carry __DATE__ and
__TIME__ respectively. Reading them from the ELF guarantees the filename
timestamp matches exactly the one the firmware reports at boot. No -g flag required.
Artifacts written with timestamp suffix (e.g. tasmota-4M-2026-05-01T19-02-06):
.bin, .bin.gz, .factory.bin (ESP32) -> build_output/firmware/
.elf -> build_output/firmware/
.map.gz -> build_output/map/
support_rtc.ino: mtime_P introduced as a named PROGMEM variable so nm can
locate __TIME__ by symbol name on all platforms, including ESP32 where
PSTR() is a no-op. Flash impact: +4 B; all other memory unchanged.
- Replace broken "http" and "://" in file condition with file.startswith(("http://", "https://")) — the original always evaluated "http" as truthy and only tested for "://".
- Strip whitespace and skip blank lines from custom_files_upload entries, matching the pattern in solidify-from-url.py.
- Resolve relative local paths against $PROJECT_DIR rather than the build-time CWD.
- solidify_all_python.be imports tasmota_defines during solidification, but the actual file is generated post-compilation by gen-berry-defines.py. If it doesn't exist yet, solidification fails. Create an empty stub before calling prepareBerryFiles so the import succeeds regardless of build order.
* Add local file support to solidify-from-url.py and fix URL rename alias bug
- Add support for local .be file paths (absolute or PROJECT_DIR-relative) in prepareBerryFiles used by custom_berry_solidify project option in solidify-from-url.py
- Fix URL path to use "/" as separator instead of os.path.sep, and pass the rename alias to addHeaderFile so the solidified header name matches the actual target filename
* solidify-from-url: replace compiled berry binary with berry_port Python interpreter
- Remove ensureBerry() and the shell invocation of the compiled `berry` binary.
- Instead run solidify_all_python.be via `python3 -m berry_port`, matching how gen-berry-structures.py drives solidification for all other berry modules.
- Use Popen to filter routine per-file output and call env.Exit on failure.
* wrap printf with stubs
* Remove flash savings message from wrap_printf
Removed print statement indicating flash savings for ESP8266.
* safe more by using rom function
* Comment out check-wrapped-lwip-sntp-calls.py script
Comment out the check-wrapped-lwip-sntp-calls.py script in platformio.ini.
* Delete pio-tools/check-wrapped-lwip-sntp-calls.py
The ESP8266 SDK automatically invokes sntp_init() via
netif_sta_status_callback on every WiFi reconnect. This results in repeated
allocations of UDP PCBs (udp_new()), leading to heap exhaustion and
potential lwIP timeout list corruption due to unmatched sntp_stop() calls.
Tasmota does not use the lwIP SNTP client and relies solely on WifiGetNtp()
for time synchronization. To avoid unnecessary resource usage, wrap and
neutralize sntp_init() and sntp_stop() with no-op implementations.
This prevents UDP PCB allocations and avoids issues caused by repeated
initialization during reconnect cycles.
Additionally, a PlatformIO post-build script has been added to validate
that the linker wraps are correctly applied. The script runs after ELF
generation and uses xtensa-lx106-elf-nm to inspect symbols, ensuring that
the __wrap_sntp_init and __wrap_sntp_stop functions are present in the
final firmware. If the wrappers are missing, the build fails.
Confirmed via firmware disassembly:
- Single call site in netif_sta_status_callback
- Requires linker wraps: --wrap=sntp_init,--wrap=sntp_stop
Fixes: #24566
* simplify post_esp32.py
* make sure path has correct "\" or "/" regarding OS
* add os specific path separators
* more path possible issues corrections
* add function to normpath cmd
* set board_build.variants_dir = variants/tasmota correctly for OS
* use OBJCOPY for full esptool path
* Update PULL_REQUEST_TEMPLATE.md
* Platform 2025.07.31 Tasmota Arduino Core 3.1.3.250712 based on IDF 5.3.3.250702