diff --git a/README.md b/README.md index fd7261c8..de1b67d0 100644 --- a/README.md +++ b/README.md @@ -598,12 +598,28 @@ Utilise the Solcast Developer Tools to examine exposed attributes, as their stru | Name | Type | Attributes | Unit | Description | | ------------------------------ | ----------- | ----------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `API Last Polled` | date/time | N | `datetime` | Date/time when the API data was polled. | +| `API Last Polled` | date/time | Y | `datetime` | Date/time when the API data was polled. | | `API Limit` | number | N | `integer` | Total times the API can been called in a 24 hour period[^1]. | | `API used` | number | N | `integer` | Total times the API has been called today (API counter resets to zero at midnight UTC)[^1]. | | `Hard Limit Set` | number | N | `float` | `False` if not set, else value in `kilowatts`. | | `Hard Limit Set ******AaBbCc` | number | N | `float` | Individual account hard limit. `False` if not set, else value in `kilowatts`. | -| `Rooftop(s) name` | number | Y | `kWh` | Total forecast for rooftop today (attributes contain the solcast rooftop setup)[^2]. | +| `Rooftop name` | number | Y | `kWh` | Total forecast for rooftop today (attributes contain the solcast rooftop setup)[^2]. | + +`API Last Polled` attributes include the following, but only if auto-update is enabled: + +* `next_auto_update`: The UTC time of the next scheduled auto-update. +* `auto_update_divisions`: The number of configured auto-updates for each day. +* `auto_update_queue`: A maximum of 48 future auto-updates currently in the queue. + +`Rooftop name` attributes include: + +* `name`: The site name configured at solcast.com. +* `resource_id`: The site ID. +* `capacity`: Site capacity in AC power. +* `capacity_dc`: Site capacity in DC power. +* `azimuth` / `tilt`: Panel orientation. +* `install_date`: Configured installation date. +* `loss_factor`: Configured "loss factor". [^1]: API usage information is internally tracked and may not match actual account usage. @@ -858,6 +874,7 @@ v4.2.8 * Fix an issue with transitioning from granular to legacy dampening by @autoSteve * Fix an issue with using multiple hard limits by @autoSteve * Fix an issue with stale start when auto-update is enabled by @autoSteve +* Add auto-update attributes to api_last_polled by @autoSteve * Upgrade data files from v3 integration by @autoSteve * Config and options flows check valid API key and sites available by @autoSteve * Add re-auth and reconfigure flows by @autoSteve diff --git a/custom_components/solcast_solar/coordinator.py b/custom_components/solcast_solar/coordinator.py index 25a73da7..b5be1b0e 100644 --- a/custom_components/solcast_solar/coordinator.py +++ b/custom_components/solcast_solar/coordinator.py @@ -312,6 +312,17 @@ def format_intervals(intervals) -> list[str]: ", ".join(format_intervals(intervals_tomorrow)), ) + def _get_auto_update_details(self) -> dict[str, Any]: + """Return attributes for the last updated sensor.""" + + if self.solcast.options.auto_update > 0: + return { + "next_auto_update": self._intervals[0], + "auto_update_divisions": self.divisions, + "auto_update_queue": self._intervals[:48], + } + return {} + async def __forecast_update(self, force: bool = False, completion: str = "", need_history_hours: int = 0) -> None: """Get updated forecast data.""" @@ -487,6 +498,8 @@ def get_sensor_extra_attributes(self, key: str = "") -> dict[str, Any] | None: ) if to_return is not None: ret.update(to_return) + if key == "lastupdated": + ret.update(self._get_auto_update_details()) return ret def get_site_sensor_value(self, roof_id: str, key: str) -> float | None: diff --git a/custom_components/solcast_solar/sensor.py b/custom_components/solcast_solar/sensor.py index 48cfd271..20feb5e4 100755 --- a/custom_components/solcast_solar/sensor.py +++ b/custom_components/solcast_solar/sensor.py @@ -414,7 +414,9 @@ def __init__( async def async_added_to_hass(self) -> None: """Entity about to be added to hass, so set recorder excluded attributes.""" await super().async_added_to_hass() - if ( + if self.entity_id.startswith("sensor.solcast_pv_forecast_api_last_polled"): + self._state_info["unrecorded_attributes"] = frozenset(["next_auto_update", "auto_update_divisions", "auto_update_queue"]) + elif ( self.entity_id.startswith("sensor.solcast_pv_forecast_forecast_today") or self.entity_id.startswith("sensor.solcast_pv_forecast_forecast_tomorrow") or self.entity_id.startswith("sensor.solcast_pv_forecast_forecast_day") diff --git a/custom_components/solcast_solar/solcastapi.py b/custom_components/solcast_solar/solcastapi.py index 9c993f1f..51fc99de 100644 --- a/custom_components/solcast_solar/solcastapi.py +++ b/custom_components/solcast_solar/solcastapi.py @@ -3084,7 +3084,7 @@ def _remove_issues(): # If auto-update is enabled yet the prior forecast update was manual then do not raise an issue. raise_issue = None if self._data["auto_updated"] == 0 and self.entry.options["auto_update"] != 0 else raise_issue if raise_issue is not None and issue_registry.async_get_issue(DOMAIN, raise_issue) is None: - _LOGGER.warning("Raise issue for missing forecast data") + _LOGGER.warning("Raise issue `%s` for missing forecast data", raise_issue) ir.async_create_issue( self.hass, DOMAIN,