mirror of
https://github.com/Legolas-2025/Standalone-electricity-price-ticker.git
synced 2026-08-17 12:34:55 +02:00
Update CHANGELOG for v7.2 release
Document bug fixes and improvements for v7.2 release, including button responsiveness and screen control issues.
This commit is contained in:
+205
@@ -2,6 +2,211 @@
|
|||||||
|
|
||||||
All notable changes to this project are documented here.
|
All notable changes to this project are documented here.
|
||||||
|
|
||||||
|
## v7.2 - Button Robustness & Screen-Control Fixes (2026-08-04)
|
||||||
|
|
||||||
|
**Summary**
|
||||||
|
|
||||||
|
Bug-fix release that resolves the three control glitches reported for the v7.1
|
||||||
|
firmware on the Seeed XIAO ESP32‑C3:
|
||||||
|
|
||||||
|
- "It is 20:35 and I cannot scroll the values of the primary screen."
|
||||||
|
- "Double click does not switch to the secondary screen."
|
||||||
|
- "Strange behaviour at the end of the day, if there is no tomorrow's data
|
||||||
|
available yet and the time is let's say 22:15."
|
||||||
|
|
||||||
|
No fee/VAT math, NVS layout, API scheduling or 48-hour scrolling behaviour
|
||||||
|
was changed. The v7.1 negative-price provider fee logic is preserved
|
||||||
|
verbatim.
|
||||||
|
|
||||||
|
### Fix 1 – Primary-screen scroll works at any hour of the day
|
||||||
|
|
||||||
|
**Symptom**
|
||||||
|
|
||||||
|
Clicking the button on the primary screen appeared to do nothing — the
|
||||||
|
display stayed on the current hour and refused to advance.
|
||||||
|
|
||||||
|
**Root cause (two compounding bugs)**
|
||||||
|
|
||||||
|
1. `displayPriceRow()` only blanked past hours while `currentHour < 22`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
if (localHourIndex < currentHour && currentHour < 22) {
|
||||||
|
lcd.print(" "); return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
After 22:00 the guard fell through, so the screen was allowed to repaint
|
||||||
|
already-finished morning hours (00:00 – 21:59). The moment the user
|
||||||
|
scrolled forward, the new "top" hour was visually overwritten by the
|
||||||
|
previous morning's data, making the screen look frozen.
|
||||||
|
|
||||||
|
2. `displayPrimaryList()` contained an override:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
if (currentHour >= 21 && timeOffsetHours > 0) {
|
||||||
|
displayStartHourOffset = 21 + timeOffsetHours;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
From 21:00 onward this pinned the top row at `21 + offset`. At 22:15
|
||||||
|
every click computed start = 22+offset, was then clamped to 21+offset,
|
||||||
|
and the user saw no movement.
|
||||||
|
|
||||||
|
**Fix**
|
||||||
|
|
||||||
|
- `displayPriceRow()`: simplified the past-hour guard to
|
||||||
|
`if (localHourIndex < currentHour) blank();` so past hours of today are
|
||||||
|
hidden at every hour of the day, not just before 22:00.
|
||||||
|
- `displayPrimaryList()`: removed the `currentHour >= 21` override
|
||||||
|
entirely. Past-hour blanking is now handled correctly by Fix 1a, so the
|
||||||
|
override is no longer needed.
|
||||||
|
|
||||||
|
### Fix 2 – Double-click reliably toggles to the secondary screen
|
||||||
|
|
||||||
|
**Symptom**
|
||||||
|
|
||||||
|
A quick double-click did nothing — the display stayed on the primary
|
||||||
|
price view. In some cases the screen showed a stuck "Long press detected!
|
||||||
|
Release to refresh" message right after the device booted or was reset.
|
||||||
|
|
||||||
|
**Root cause**
|
||||||
|
|
||||||
|
The double-click path itself was correct; it was being starved by a false
|
||||||
|
"Long press detected!" that fired immediately after every reset. On the
|
||||||
|
ESP32-C3 the button pin (configured as `INPUT_PULLUP`) floats HIGH for a
|
||||||
|
few seconds during boot while the internal pull-up is settling and
|
||||||
|
power-rail noise is ringing. Because `buttonPressStartTime` is
|
||||||
|
initialised to `0`, the long-press detector's predicate
|
||||||
|
`millis() - buttonPressStartTime >= 3000` evaluated to
|
||||||
|
`millis() >= 3000` a few seconds after boot — the firmware interpreted
|
||||||
|
the floating-pin noise as a genuine 3-second hold, cleared the LCD to:
|
||||||
|
|
||||||
|
```
|
||||||
|
Long press detected!
|
||||||
|
Release to refresh
|
||||||
|
```
|
||||||
|
|
||||||
|
…and from then on the user could not see any prices to click on
|
||||||
|
(single- and double-click recognisers both still ran, but their visible
|
||||||
|
effect was hidden behind the long-press splash).
|
||||||
|
|
||||||
|
**Fix**
|
||||||
|
|
||||||
|
Added a single new global flag and gated the long-press detector on it:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// New flag, set true the first time the pin is observed LOW after boot
|
||||||
|
bool buttonEverReleased = false;
|
||||||
|
|
||||||
|
// In the "reading went LOW" branch:
|
||||||
|
if (reading == LOW) {
|
||||||
|
buttonPressStartTime = millis();
|
||||||
|
longPressDetected = false;
|
||||||
|
buttonEverReleased = true; // v7.2
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the long-press trip block:
|
||||||
|
if (buttonState == LOW && !longPressDetected && buttonEverReleased) { // v7.2
|
||||||
|
if (millis() - buttonPressStartTime >= longPressThreshold) {
|
||||||
|
longPressDetected = true;
|
||||||
|
// ... show "Long press detected! Release to refresh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The detector now refuses to fire until the user (or the power-rail noise)
|
||||||
|
has released the button at least once. The v7.1 button logic (50 ms
|
||||||
|
debounce, 3 s long-press threshold, 500 ms double-click window, TTP223
|
||||||
|
timing) is otherwise preserved verbatim.
|
||||||
|
|
||||||
|
### Fix 3 – End-of-day scroll is stable with no tomorrow data
|
||||||
|
|
||||||
|
**Symptom**
|
||||||
|
|
||||||
|
Around 22:00 – 23:59 with no tomorrow data in the buffer, scrolling
|
||||||
|
through the primary screen produced a screen full of blank past-hour
|
||||||
|
rows, or wrapped the start hour back to 00:00 in a confusing way.
|
||||||
|
|
||||||
|
**Root cause**
|
||||||
|
|
||||||
|
`advanceDisplayOffset()` contained a hack:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
if (allowedAhead < 2 && currentHour >= 21 && !isTomorrowDataAvailable)
|
||||||
|
allowedAhead = 2;
|
||||||
|
```
|
||||||
|
|
||||||
|
At 22:00 (with no tomorrow data) this let the user click past hour 23
|
||||||
|
into "24:00 / 25:00". `displayStartHourOffset` then exceeded
|
||||||
|
`maxOffsetLimit = 23` and the wrap logic:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
if (displayStartHourOffset > maxOffsetLimit)
|
||||||
|
displayStartHourOffset %= (maxOffsetLimit + 1);
|
||||||
|
```
|
||||||
|
|
||||||
|
…wrapped it back to 0. Combined with the buggy past-hour blanking in
|
||||||
|
Fix 1a, the result was a screen full of stale blank rows from 00:00 to
|
||||||
|
21:59.
|
||||||
|
|
||||||
|
**Fix**
|
||||||
|
|
||||||
|
Removed the `allowedAhead = 2` hack. The natural cap is now sufficient:
|
||||||
|
|
||||||
|
- 22:00 → can step 22 → 23, then wraps back to current
|
||||||
|
- 23:00 → cannot step forward at all
|
||||||
|
|
||||||
|
No wrap to 00:00 of the previous day is reachable any more, and Fix 1a
|
||||||
|
ensures any past hour that does briefly land on the screen is blanked
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
### Fix 4 (bonus) – Auto-return timer now resets on every click
|
||||||
|
|
||||||
|
**Symptom**
|
||||||
|
|
||||||
|
Scrolling through the 20-line secondary status page (4 lines at a time)
|
||||||
|
did not push the 10 s auto-return-to-top timeout forward — the display
|
||||||
|
could jump back to the primary price view mid-read.
|
||||||
|
|
||||||
|
**Root cause**
|
||||||
|
|
||||||
|
`lastButtonActivity` and `autoScrollExecuted` were only updated inside the
|
||||||
|
primary-list branches of `advanceDisplayOffset()`. The secondary-list
|
||||||
|
branch scrolled the offset but did not touch the timer.
|
||||||
|
|
||||||
|
**Fix**
|
||||||
|
|
||||||
|
Moved the two resets to the very top of `advanceDisplayOffset()`:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void advanceDisplayOffset() {
|
||||||
|
// Any successful click (single, double, or long-press-release) ends up
|
||||||
|
// here, so this is the single place that resets the auto-return timer.
|
||||||
|
lastButtonActivity = millis();
|
||||||
|
autoScrollExecuted = false;
|
||||||
|
// ... rest of the function unchanged
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other changes (cosmetic / non-behavioural)
|
||||||
|
|
||||||
|
- Filename and three user-visible version strings bumped to v7.2:
|
||||||
|
- `connectToWiFi()` splash: `"Elec. Rate SI v7.1"` → `"v7.2"`
|
||||||
|
- `displaySecondaryList()` credit line (line 18): `"price ticker v7.1"` → `"v7.2"`
|
||||||
|
- `setup()` debug banner: `"Starting Dynamic Electricity Ticker v7.1 (Neg Price Fee) - DST-SAFE"`
|
||||||
|
→ `"Starting Dynamic Electricity Ticker v7.2 (Button Robustness) - DST-SAFE"`
|
||||||
|
- Inline comments added at each fix site explaining what v7.1 did wrong,
|
||||||
|
so future maintainers do not re-introduce the overrides.
|
||||||
|
- New global flag `bool buttonEverReleased` (see Fix 2).
|
||||||
|
|
||||||
|
### Files changed
|
||||||
|
|
||||||
|
| File | Change |
|
||||||
|
|---|---|
|
||||||
|
| `ESP32_standalone_electricity_ticker_7_2.ino` | Filename, header comment, `buttonEverReleased` flag, `handleButton()` long-press gate, `displayPriceRow()` past-hour guard, `displayPrimaryList()` removed override, `advanceDisplayOffset()` timer reset, three version strings |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v7.1 - Negative Price Provider Fee (2026-04-06)
|
## v7.1 - Negative Price Provider Fee (2026-04-06)
|
||||||
|
|
||||||
**Summary**
|
**Summary**
|
||||||
|
|||||||
Reference in New Issue
Block a user