Skip to content

Dev#10

Merged
azebro merged 8 commits into
mainfrom
dev
Mar 5, 2026
Merged

Dev#10
azebro merged 8 commits into
mainfrom
dev

Conversation

@azebro
Copy link
Copy Markdown
Owner

@azebro azebro commented Mar 5, 2026

This pull request introduces restart-safe sensor state restoration and improves the persistence and recovery of node and energy data in the PyTap Home Assistant integration. It also enhances logging clarity and robustness of sensor value restoration, and adds documentation for a new PV production dashboard.

Restart-safe state restoration and persistence:

  • Coordinator now persists and restores last known node readings, so sensors remain available with their most recent value after a restart, even before new data arrives. This is reflected in both the README.md and the implementation in coordinator.py, with new helpers for building, merging, and saving node snapshots. [1] [2] [3] [4] [5]

Sensor restoration improvements:

  • Sensor entities now robustly restore their last known value from Home Assistant state cache, using a new _coerce_restored_state_value helper to convert string states to native numeric types. This ensures sensors do not become unavailable after a restart if prior data exists. [1] [2] [3] [4]

Logging enhancements:

  • Changed several logging statements from warning to info in coordinator.py and parser.py for infrastructure and node table events, reducing unnecessary warning noise and improving log clarity. [1] [2] [3]

Documentation updates:

  • Added a new dashboards/pv_production.md file detailing the Lovelace dashboard for PV panel layout and connectivity, including color scaling formulas, grid arrangement, YAML structure, and template sensor aggregation.

- Implemented a new Lovelace dashboard for PV production with two views:
  1. PV Panel Layout displaying daily energy production per panel.
  2. Panel Connectivity showing the number of readings received today per panel.

- Created template sensors for max-value aggregation of daily energy and readings across all panels, improving performance by offloading calculations to the server-side.

- Enhanced unit tests for sensor state restoration, ensuring proper handling of restored states and fallback mechanisms during component startup.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves restart behavior for the PyTap Home Assistant integration by persisting/restoring coordinator node readings (“snapshots”) and enhancing sensor-side restoration so entities can remain available with last known values after restarts.

Changes:

  • Persist and restore node_snapshots in the coordinator store, and merge restored snapshot + energy accumulator state into coordinator.data["nodes"] on startup.
  • Enhance sensor entity restoration with _coerce_restored_state_value and an additional fallback to HA’s last state when RestoreSensor data isn’t available.
  • Add PV production dashboard YAML + documentation, plus small logging level adjustments and updated docs/planning notes.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
custom_components/pytap/coordinator.py Adds node snapshot persistence and startup restoration/merging logic.
custom_components/pytap/sensor.py Adds restored-state coercion helper and expands startup restore behavior for sensors.
custom_components/pytap/pytap/core/parser.py Downgrades a node-table completion log line from warning to info.
tests/test_sensor.py Adds unit tests for coercion and integration-style restart restoration scenarios.
tests/test_coordinator_persistence.py Adds coverage for loading/saving node_snapshots.
README.md Documents restart-safe availability behavior.
docs/implementation.md Documents new persistence behavior (energy + node snapshots).
planning/future_considerations.md Updates roadmap notes (binary sensor “will not implement”, removes barcode modification item).
dashboards/tigo.yaml Adds template sensors for max aggregation used by the dashboard.
dashboards/pv_production_dashboard.yaml Adds a multi-view Lovelace dashboard layout for panel visualization.
dashboards/pv_production.md Adds setup/usage documentation for the dashboard and template sensors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +19 to +25
**Template sensors** — include `tigo.yaml` in your HA configuration (e.g. via `template: !include tigo.yaml` or a packages directory). It provides:

| Sensor | Entity ID | Purpose |
|--------|-----------|---------|
| Tigo Max Daily Energy | `sensor.tigo_max_daily_energy` | Highest `_daily_energy` across all 26 panels (kWh) |
| Tigo Max Readings Today | `sensor.tigo_max_readings_today` | Highest `_readings_today` across all 26 panels |

Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

tigo.yaml defines an additional sensor.tigo_max_power used by the Page 3 “Panel Power” view in the dashboard YAML, but this doc’s template-sensor list only mentions the daily-energy and readings aggregators. Consider documenting the max-power sensor as well so setup instructions are complete.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

Comment thread custom_components/pytap/sensor.py Outdated
Comment thread custom_components/pytap/sensor.py Outdated
Comment on lines +54 to +66
def _coerce_restored_state_value(raw_state: str, sensor_key: str) -> int | float | None:
"""Convert a restored state string to a native numeric sensor value."""
if raw_state in (STATE_UNKNOWN, STATE_UNAVAILABLE, "None", "none", ""):
return None

try:
numeric_value = float(raw_state)
except (TypeError, ValueError):
return None

if sensor_key == "readings_today":
return int(numeric_value)

Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

_coerce_restored_state_value can return non-finite floats (e.g., 'nan', 'inf') and will raise in the readings_today path (int(float('nan')) throws). Add a finite check (e.g., math.isfinite) after parsing, and for readings_today only coerce when the value is a whole number to avoid silently truncating strings like '42.9'.

Copilot uses AI. Check for mistakes.
Comment thread dashboards/pv_production.md Outdated
Comment thread dashboards/pv_production.md Outdated
Comment on lines +132 to +144
## tigo.yaml — Template Sensors

Server-side Jinja2 template sensors that aggregate all 24 panel values:

```yaml
template:
- sensor:
- name: "Tigo Max Daily Energy" # sensor.tigo_max_daily_energy
state: "{{ [all 24 _daily_energy states] | map('float', 0) | max }}"

- name: "Tigo Max Readings Today" # sensor.tigo_max_readings_today
state: "{{ [all 24 _readings_today states] | map('float', 0) | max }}"
```
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

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

Later in the doc, the “tigo.yaml — Template Sensors” section again references aggregating “all 24 panel values” / “all 24 _daily_energy states”, but tigo.yaml in this PR enumerates 26 panels. Please update these placeholders to 26 (or make the wording panel-count-agnostic).

Copilot uses AI. Check for mistakes.
Adam Zebrowski and others added 2 commits March 5, 2026 07:56
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 5, 2026

@azebro I've opened a new pull request, #11, to work on those changes. Once the pull request is ready, I'll request review from you.

azebro and others added 3 commits March 5, 2026 07:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@azebro azebro merged commit b69c8fa into main Mar 5, 2026
8 checks passed
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.

3 participants