Repository navigation
Entity cleanup, rain-forecast device_class fix, and PM ET0 / nowcast diagnostics - #157
Merged
Merged
Conversation
…and add PM ET0 / nowcast diagnostics - Remove switch.ws_enable_local_forecaster and number.ws_forecaster_learning_rate from the entity registry on every setup: leftovers of the unreleased v2.0 AI/local-forecaster work, confirmed dead (zero code references, no trace in git history under those unique_ids either). - Drop the moisture device_class from binary_sensor.ws_rain_expected_1h; that class is reserved for a current wetness/leak reading, not a forecast flag. - Add a Repairs issue explaining when sensor.ws_et0_penman_monteith silently never appears because no solar_radiation source is configured. - Add an optional illuminance-derived solar radiation fallback for PM ET0, tagged via a radiation_source attribute so consumers know it's an estimate. - Expose nowcast staleness (nowcast_fetched_at / nowcast_stale attributes) on binary_sensor.ws_rain_expected_1h, and fall back to a local Zambretti-derived rain-expected signal (tagged source: local_fallback) when the Open-Meteo nowcast has failed or gone stale, rather than holding a stale value or always going unavailable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six independent fixes/improvements verified against a live v2.8.1 instance on 2026-09-26. Each section below can be reviewed and reverted independently even though they ship as one PR. Checked open issues/PRs before opening this (twice: 2026-09-26 at task start and again just before opening) - nothing overlapping.
1. Remove orphaned local-forecaster entities
switch.ws_enable_local_forecasterandnumber.ws_forecaster_learning_rateshow up on some live instances asrestored: true/unavailable. A full-tree grep (switch.py,number.py,const.py,coordinator.py,learning_state.py,__init__.py) confirms zero current references.Note on provenance: these unique IDs don't appear anywhere in this repo's git history either (427 commits, not shallow) - not even in
5cefe8d("remove v2.0 AI/LLM code from public release"), the commit that stripped the closest related feature (WSAIProviderSelect, AI refresh-hours/token-budget numbers). They're leftovers of a pre-release build of the still-unreleased v2.0 AI/local-forecaster branch that a few instances briefly ran. Confirmed dead either way.Cleanup runs on every setup/reload (not tied to a config-version bump, since affected instances are already on the latest schema) and only touches these two unique IDs for the current config entry - it does not touch any other restored/unavailable entity a user may have legitimately disabled.
2. Fix
device_classon the rain-expected sensorWSRainExpected1h(binary_sensor.ws_rain_expected_1h) usedBinarySensorDeviceClass.MOISTURE, which Home Assistant reserves for a current wetness/leak reading, not a forecast flag. No binary sensor device_class fits a forecast prediction, so it's now unset.3. Make PM ET₀ absence diagnosable
sensor.ws_et0_penman_monteithis gated onenable_solar_forecastbut silently never appeared when the sources config had nosolar_radiationkey. A Repairs issue (et0_pm_unavailable) now explains this and points at the fix (map a solar radiation sensor, or enable the new illuminance fallback from #4).4. Add a lux -> W/m² fallback source for PM ET₀
New optional "illuminance fallback" toggle (Solar Forecast step of the config/options flow,
CONF_ET0_ILLUMINANCE_FALLBACK): when nosolar_radiationsource is mapped but an illuminance sensor is, derives an approximate solar radiation using the standard ~0.0079 W/m² per lux daylight conversion factor. The resultingsensor.ws_et0_penman_monteithvalue is tagged with aradiation_sourceattribute (sensorvsilluminance_estimate) so downstream consumers know it's lower-confidence than a real pyranometer reading. The conversion's real-world error margin (roughly ±25%, varying with sky conditions and sun elevation) is documented inconst.pyand the README FAQ.5. Make nowcast staleness visible
binary_sensor.ws_rain_expected_1hdepends on_async_fetch_nowcast()(Open-Meteominutely_15). The coordinator's internal_nowcast_fetched_atis now exposed asnowcast_fetched_at/nowcast_staleattributes on the entity, and the nowcast cache is considered stale once older than 2x the fetch interval.6. Add a local-only nowcast fallback
When the Open-Meteo nowcast has failed or gone stale (per #5's threshold),
binary_sensor.ws_rain_expected_1hnow falls back to a rain-expected signal derived from the existing local pressure-trend/Zambretti path (sensor.ws_zambretti_forecast's Z-number -> implied rain probability) instead of just going unavailable. This is coarser than the 15-minute NWP nowcast, so the entity'ssourceattribute is taggednowcastorlocal_fallbackaccordingly. The entity only goes explicitlyunavailablewhen neither a fresh nowcast nor a Zambretti reading exists at all.Testing
tests/test_migration.py::TestOrphanedForecasterCleanup(item 1)tests/test_binary_sensor.py(items 2, 5, 6 - device_class, availability, source/staleness attributes)tests/test_coordinator.py::TestEt0PmUnavailableIssue,TestSolarRadiationForEt0(items 3, 4)tests/test_coordinator.py::TestComputeNowcast(items 5, 6 - fresh/stale/never-fetched/no-fallback paths)_compute()into_compute_nowcast()for direct unit testing.ruff check/ruff format --checkclean.🤖 Generated with Claude Code