Skip to content

Fix: TFT version precision and format upgrade (sensor → text, 2-segment versioning)#98

Merged
edwardtfn merged 4 commits intomainfrom
v9999.99.9
Apr 6, 2026
Merged

Fix: TFT version precision and format upgrade (sensor → text, 2-segment versioning)#98
edwardtfn merged 4 commits intomainfrom
v9999.99.9

Conversation

@edwardtfn
Copy link
Copy Markdown
Owner

@edwardtfn edwardtfn commented Apr 6, 2026

What changed

The TFT version is now reported as a 2-segment string (e.g. 16.1) instead of a plain integer.

Problem

The previous implementation stored the TFT version as a float sensor, which caused IEEE 754
precision loss on the ESP32 — 16.1 was displayed in Home Assistant as 16.1000003814697.

Solution

  • version_tft is now a text_sensor, consistent with version_blueprint and version_esphome
  • The Nextion boot params parser now stores the raw version string as received (e.g. "16.1")
  • A new tft_ver_gte() function handles 2-segment (major.minor) numeric version comparison, correctly handling cases like 16.12 > 16.2
  • The Blueprint compares TFT versions using | float(0) filters, avoiding both lexicographic pitfalls and the need for parts-splitting logic
  • The fire_ha_event version payload now sends the TFT version as a string, preserving the decimal format end-to-end into Home Assistant

Summary by CodeRabbit

  • New Features

    • Added a TFT version comparison helper to validate and compare version strings (accepts "major" or "major.minor").
  • Bug Fixes

    • Improved TFT version validation to reject malformed inputs and avoid incorrect numeric parsing.
    • Switched version checks and logs to use the validated string form to prevent spurious comparisons.
  • Refactor

    • Migrated TFT version state from numeric to string representation and updated related event payloads and sensors.

…nt versioning)

## What changed

The TFT version is now reported as a 2-segment string (e.g. `16.1`) instead of a plain integer.

### Problem

The previous implementation stored the TFT version as a `float` sensor, which caused IEEE 754
precision loss on the ESP32 — `16.1` was displayed in Home Assistant as `16.1000003814697`.

### Solution

- `version_tft` is now a `text_sensor`, consistent with `version_blueprint` and `version_esphome`
- The Nextion boot params parser now stores the raw version string as received (e.g. `"16.1"`)
- A new `tft_ver_gte()` function handles 2-segment (`major.minor`) numeric version comparison,
  correctly handling cases like `16.12 > 16.2`
- The Blueprint compares TFT versions using `| float(0)` filters, avoiding both lexicographic
  pitfalls and the need for parts-splitting logic
- The `fire_ha_event` version payload now sends the TFT version as a string, preserving the
  decimal format end-to-end into Home Assistant
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

📝 Walkthrough

Walkthrough

Migrates TFT version handling from numeric floats to validated version strings. Adds tft_ver_gte() to parse and compare major[.minor] strings conservatively, converts version_tft to a text sensor, updates YAML consumers to use string emptiness checks, and replaces numeric logging/formatting with string-based logs.

Changes

Cohort / File(s) Summary
Version Comparison Helper
components/nspanel_easy/versioning.h, components/nspanel_easy/versioning.cpp
Added tft_ver_gte(const std::string &version, const std::string &min_version) which parses major or major.minor, rejects malformed/partial inputs, and compares major then minor.
YAML: upload / addon
esphome/nspanel_esphome_addon_upload_tft.yaml
Switched comparison to tft_ver_gte(...) and changed informational log to use %s with version_tft->state.c_str().
YAML: hardware display
esphome/nspanel_esphome_hw_display.yaml
Replaced numeric > 0/<= 0 checks with empty() string checks and updated TFT version logging to %s / TFT: UNKNOWN when empty.
YAML: page boot / event parsing
esphome/nspanel_esphome_page_boot.yaml
Removed strtof parsing; added string validation (digits + optional single dot) and publish of validated string or empty string when invalid; adjusted wake/gate logic to use empty checks.
YAML: version orchestration
esphome/nspanel_esphome_version.yaml
Replaced float sensor with text_sensor for version_tft; updated logs to %s; replaced numeric comparisons/NaN handling with tft_ver_gte() and string emptiness checks; event payload now uses the raw string state.

Sequence Diagram(s)

(Skipped — changes are localized helpers and YAML wiring; no new multi-component sequential flow requiring visualization.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped through dots and digits bright,

Parsed majors first, then minors right.
No floating ghosts or trailing mess,
Strings stand true — I dance, no stress! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: converting TFT version storage from a float sensor to a string text sensor with 2-segment versioning format, which directly addresses the IEEE 754 precision loss problem described in the PR objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v9999.99.9

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@edwardtfn edwardtfn linked an issue Apr 6, 2026 that may be closed by this pull request
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/nspanel_easy/versioning.cpp`:
- Around line 36-46: The sscanf checks (ver_fields/min_fields) allow partial
matches like "16.", "16x", or "16.1.2"; update version parsing in versioning.cpp
to strictly validate the full input before or instead of sscanf: for each input
string (version and min_version) enforce a full-match pattern such as ^\d+$ or
^\d+\.\d+$ (e.g., via std::regex_match) and only then parse into ver_maj/ver_min
and min_maj/min_min (or use sscanf with a trailing-char check "%d.%d%c" and
reject if an extra char is consumed); return false for any string that does not
exactly match the allowed formats.

In `@esphome/nspanel_esphome_page_boot.yaml`:
- Around line 67-88: The TFT version validation currently only whitelists digits
and '.' which accepts invalid values like ".", "16.", or "16..1"; update the
validation logic around ver_str so it only accepts either "major" (one or more
digits) or "major.minor" (one or more digits, a single '.', then one or more
digits): ensure the first character is a digit, allow at most one '.', disallow
trailing or leading '.', and when a '.' exists verify there are digits on both
sides; then keep the same behavior of calling
version_tft->publish_state(ver_str) only when valid and setting
system_flags.display_settings_received based on that stricter tft_ver_valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: eaf52510-56d5-421f-8aeb-9f1e40aeadc4

📥 Commits

Reviewing files that changed from the base of the PR and between 32ff761 and b9afd98.

📒 Files selected for processing (6)
  • components/nspanel_easy/versioning.cpp
  • components/nspanel_easy/versioning.h
  • esphome/nspanel_esphome_addon_upload_tft.yaml
  • esphome/nspanel_esphome_hw_display.yaml
  • esphome/nspanel_esphome_page_boot.yaml
  • esphome/nspanel_esphome_version.yaml

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
esphome/nspanel_esphome_page_boot.yaml (1)

67-68: Use strict numeric parsing for boot parameters.

Lines 67–68 parse display settings with atoi(), which accepts malformed input (e.g., signed prefixes, whitespace). Negative values wrap to large uint8_t values when assigned, potentially bypassing the > 0 gate on line 88. Consider using strtoul() with full input validation and range checking to reject invalid input outright.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@esphome/nspanel_esphome_page_boot.yaml` around lines 67 - 68, The current
boot parsing uses atoi on params[2]/params[3] (assigned to display_mode and
display_charset) which accepts malformed input and can produce negative values
that wrap into large uint8_t; replace with strtoul-based parsing: call strtoul
on each params[i], check endptr consumes the whole string (no leading/trailing
garbage), ensure errno is cleared/checked for overflow, and validate the numeric
value is within the allowed range (e.g., 0–255 and if you rely on a >0 gate
later ensure >0 when required) before casting/assigning to display_mode and
display_charset; if validation fails, reject the parameter (return error/log)
rather than silently accepting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@esphome/nspanel_esphome_page_boot.yaml`:
- Around line 67-68: The current boot parsing uses atoi on params[2]/params[3]
(assigned to display_mode and display_charset) which accepts malformed input and
can produce negative values that wrap into large uint8_t; replace with
strtoul-based parsing: call strtoul on each params[i], check endptr consumes the
whole string (no leading/trailing garbage), ensure errno is cleared/checked for
overflow, and validate the numeric value is within the allowed range (e.g.,
0–255 and if you rely on a >0 gate later ensure >0 when required) before
casting/assigning to display_mode and display_charset; if validation fails,
reject the parameter (return error/log) rather than silently accepting.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8bc1f272-c319-4da8-93f7-35d6c45fc74b

📥 Commits

Reviewing files that changed from the base of the PR and between b9afd98 and 4ccf805.

📒 Files selected for processing (2)
  • components/nspanel_easy/versioning.cpp
  • esphome/nspanel_esphome_page_boot.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/nspanel_easy/versioning.cpp

@edwardtfn edwardtfn linked an issue Apr 6, 2026 that may be closed by this pull request
@edwardtfn edwardtfn merged commit c4f9049 into main Apr 6, 2026
35 checks passed
@edwardtfn edwardtfn deleted the v9999.99.9 branch April 6, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug Versioning Enhancement tft version as seen by home assistant

1 participant