Releases: smogaone/TemHu
Release list
v2.1.0 — 2026-07-18 🌍 New Feature: Language Selection
v2.1.0 — 2026-07-18
🌍 New Feature: Language Selection (C5)
- Added a new setting C5. Language in the web UI
- Supported languages:
- 🇩🇪 Deutsch (default — shown on the display by default)
- 🇬🇧 English
- 🇫🇷 Français
- 🇨🇺 Español (Latinoamérica)
- What changes: The date and weekday shown on the Tem(H)u display adapt to the selected language:
- Weekday names (Montag / Monday / Lundi / Lunes)
- Month names (Juli / July / juillet / julio)
- Date format per locale:
- Deutsch:
18. Juli 2026 - English:
July 18, 2026 - Français:
18 juillet 2026 - Español:
18 de julio de 2026
- Deutsch:
- Language selection is saved in Flash — survives reboots
💍 New Feature: Dual Ring Mode (A6)
- Added a new setting A6. Ring: Dual Mode (outer=Hum, inner=Temp) in the web UI
- OFF (default): Both rings (outer and inner) show the same colour, driven by the currently visible page (blue = low humidity, mint = comfortable, amber = warm, etc.)
- ON: The two rings are independent and always show both values simultaneously:
- Outer ring → Humidity colour
- Inner ring → Temperature colour
- The active page value is shown at full brightness, the other at 75% — so you always know which page you are on while still seeing both metrics at a glance
- On the clock page, both rings always share the same colour regardless of this setting
- Setting is saved in Flash — survives reboots
🐛 Bug Fix: Timezone display showed wrong time after manual change
Symptom: After selecting a different timezone in the web UI (e.g. switching from Asia/Tokyo to Europe/Berlin), the display continued to show the old time. Unplugging and replugging the device only helped temporarily — after the next NTP sync the time was again incorrect.
Root cause: setenv("TZ", ...) and tzset() followed by localtime() do not work correctly on this specific ESP-IDF build used by ESPHome 2026.x. The C library's localtime() function consistently returned UTC regardless of the TZ environment variable being set.
Fix: Replaced the entire timezone conversion approach:
- Removed all
setenv()/tzset()/localtime()calls - Now uses
utcnow()(always correct UTC from NTP) + manual offset arithmetic +gmtime_r()which is guaranteed to work on this platform - Example:
local_time = UTC_epoch + (offset_minutes × 60)→gmtime_r()→ hours/minutes/date
🐛 Bug Fix: Timezone setting lost after reboot
Symptom: The selected timezone was not remembered after a power cycle. The device would show the wrong timezone until the user re-selected it in the web UI.
Fix: Added 5 NVS-backed globals that persist across reboots:
| Global | Purpose | Example (Europe/Berlin) |
|---|---|---|
tz_std_offset_min |
Standard time UTC offset (minutes) | +60 (CET = UTC+1) |
tz_dst_offset_min |
Summer time UTC offset (minutes) | +120 (CEST = UTC+2) |
tz_dst_start_month |
Month when summer time begins | 3 (March) |
tz_dst_end_month |
Month when summer time ends | 10 (October) |
tz_south_hemi |
Southern hemisphere DST logic | false |
On every boot the timezone is automatically re-applied from Flash — no manual re-selection needed.
🐛 Bug Fix: Summer/Winter time not switching automatically
Symptom: DST (Daylight Saving Time) was not applied automatically. The clock stayed on standard time in summer and vice versa.
Fix: Automatic DST detection based on current UTC month and stored DST start/end months. The display applies summer time (+1h) or winter time automatically every second without any user interaction. Hemisphere-aware: southern hemisphere countries (Australia, New Zealand, Argentina) where summer is December–February are correctly handled with inverted DST logic.
Note: The transition is month-accurate. In the transition weeks (early March, late October) the switch may be off by up to a few weeks. With Auto Timezone enabled and internet access, the correction happens within 6 hours (see below).
🌐 New Feature: Auto Timezone — IP-based detection (C6)
- New setting C6. Auto Timezone (IP-based) in the web UI — ON by default
- When enabled, the device automatically detects its timezone based on the public IP address of the connected WiFi network
- Uses the free geolocation API
ip-api.com(no account or API key required) - How it works:
- Device connects to WiFi and syncs time via NTP
- Sends a small HTTP request:
ip-api.com/json?fields=timezone,offset - API responds with the IANA timezone name (e.g.
"Europe/Berlin") and current UTC offset - Device sets timezone globals and updates the C3 dropdown automatically
- Repeats every 6 hours
- The C3 Timezone dropdown always reflects the currently active timezone
- Manual timezone selection (C3) still works at any time — Auto Timezone will re-apply after the next 6-hour refresh
- Supported timezones: covers all major world timezones (~50 entries)
- Fallback: If no internet is available, the last saved timezone from Flash is used
Practical examples:
| Situation | Result |
|---|---|
| Device at home in Berlin | Auto-detects Europe/Berlin — shows CET/CEST correctly |
| Device brought to Japan | After next WiFi connect: auto-switches to Asia/Tokyo |
| Device in Havana, Cuba | Auto-detects America/Havana — shows CDT/CST correctly |
| No internet available | Uses last saved timezone from Flash |
| VPN active on router | Detects the VPN's exit country — expected behaviour |
🔧 Internal Changes
- Removed the
api:component — device is fully standalone, Home Assistant receives data only via MQTT (optional) - Removed
setenv/tzsetfrom all code paths — replaced with offset-based calculation throughout - Added boot-time timezone re-sync: on every restart, the saved timezone dropdown selection is re-applied to ensure globals are always in sync
- Added
geo_tz_auto_detectscript (single-instance, non-blocking) - Added 6-hour periodic geolocation interval
- Added
http_request:component for IP geolocation
Device: Waveshare ESP32-S3-Touch-AMOLED 1.75"
ESPHome: 2026.7.0
## 🔧 [2.0.2] — 2026-07-17
🔧 [2.0.2] — 2026-07-17
✨ Added
- MQTT: 4 new sensor topics —
temp_min_today,temp_max_today,hum_min_today,hum_max_todayare now published every 30 s and registered via HA auto-discovery - MQTT auto-discovery extended — discovery now registers 9 sensors (previously 5); new entities appear in Home Assistant automatically without any manual configuration
🐛 Fixed
- Compiler warning: format specifier mismatch —
uint32_tvariables in uptime formatting now correctly use(unsigned int)cast; eliminates all-Wformat=warnings on ESP32 toolchain whereuint32_tresolves tolong unsigned int - Buffer overflow warning:
port_str— increased from[8]to[16]bytes incustom_mqtt.h; eliminates-Wformat-truncation=warning for port numbers - Unused function warnings —
keep_alive()anddisconnect()incustom_mqtt.hmarked with__attribute__((unused)); reserved for future use
ℹ️ Notes
- Firmware version string updated to
2.0.2(visible in web interface) - No display or UI changes — behavior identical to v2.0.1
- Flash required to apply MQTT changes; after reflash, new min/max entities appear automatically in HA
[2.0.1] — 2026-07-16
🔧 Maintenance
-
ESPHome 2026.7.0 compatibility — Migrated internal build configuration to comply with the new ESP-IDF native toolchain
requirements introduced in ESPHome 2026.7.0 -
Moved LV_DISP_DEF_REFR_PERIOD=12 from the deprecated platformio_options > build_flags to esphome > build_flags
-
Removed deprecated platformio_options block (board_build.flash_mode, board_build.f_flash, board_build.f_cpu) which are no
longer applicable when building with the native ESP-IDF toolchain
ℹ️ Notes
No functional changes — device behavior, sensors, and UI are identical to v2.0.0
🎉 Initial Release — v2.0.0
🎉 Initial Release — v2.0.0
This is the first public release of Tem(H)u.
Firmware Files
| File | Display | Description |
|---|---|---|
temhu-macro-firmware.factory(2.0.0).bin |
Tem(H)u Macro (1.75") | Full factory image — use for the first flash via USB |
Note: The factory file contains bootloader, partition table and firmware and is required for the initial flash only. All subsequent updates can be done wirelessly via the built-in web interface — no USB cable needed.