Weather
The home’s outdoor conditions from one weather.* entity, with an air-quality sensor, sun.sun for day and night, and the hourly and daily forecasts. Read-only.
Quick example
Section titled “Quick example”import { useHaWeather } from "@dashhaus/core";
/** The conditions now, with an air-quality sensor beside them and sun.sun for day and night. */export function Outside() { const { entity } = useHaWeather("weather.home", { aqiEntityId: "sensor.home_aqi", aqiScale: "US", sunEntityId: "sun.sun", loadForecasts: false, }); if (entity.state === "unavailable") return <p>No weather right now.</p>; return ( <p> {entity.state}, {entity.temperature} {entity.temperatureUnit} {entity.isDay === false && " tonight"} {entity.aqi != null && `, AQI ${entity.aqi}`} </p> );}aqi is only read with aqiScale: "US" and a sensor whose device_class is aqi: the hook won’t band a figure on a scale it can’t name. isDay comes from the sun entity you give; without one it stays unknown rather than guessing day.
Component
Section titled “Component”<HaWeather> is useHaWeather as a component that draws nothing of its own. It takes every option of the hook as a
prop, and hands the hook’s result to its child function. Use it where hooks can’t go, such as one per item of a list.
entityIdstring- The Home Assistant entity id.
children(live: HaWeatherResult) => ReactNode- Draws the hook's result. The component itself draws nothing.
useHaWeather(entityId: string, options?: HaWeatherOptions): HaWeatherResultOne live weather entity for any UI: its conditions with AQI and sun companions, today's history and the forecasts.
It reads the weather entity, its companions, today’s temperature history, and the forecasts through weather.get_forecasts.
Options
Section titled “Options”aqiEntityId?stringaqiScale?"US"- Explicit host-owned assertion that the companion uses the US AQI scale.
sunEntityId?stringname?string- Overrides Home Assistant's friendly name.
lastSeen?string- Overrides when the entity was last reachable, shown while it is unavailable.
temperatureUnit?"°C" | "°F"windSpeedUnit?"km/h" | "mph" | "m/s"pressureUnit?"hPa" | "kPa" | "inHg"hourly?HourlyForecast[]daily?DailyForecast[]history?WeatherHistory- Host-owned history override; when omitted, today's history is read from Home Assistant.
loadHistory?boolean- Set false to skip the Home Assistant history read.
loadForecasts?boolean- Set false when forecasts are supplied by another application-owned query.
onForecastError?(error: unknown) => void
Returns
Section titled “Returns”entityWeatherEntityhistoryWeatherHistoryhourly?HourlyForecast[]- Undefined until the first forecast read settles.
daily?DailyForecast[]
hourly and daily are undefined until the first forecast read settles. They are read once an hour, and the previous hour’s forecast stays up while the next loads. Pass loadForecasts={false} when another part of your app reads them.
entity: WeatherEntity
Section titled “entity: WeatherEntity”entityIdstring- The Home Assistant entity id.
namestring- Usually the home's name.
state"unavailable" | Conditiontemperature?numberapparentTemperature?numberdewPoint?numberhumidity?number- Relative humidity, percent.
pressure?numberwindSpeed?numberwindGustSpeed?numberwindBearing?number- Degrees the wind comes from, 0 = north.
uvIndex?numbertemperatureUnit"°C" | "°F"windSpeedUnit"km/h" | "mph" | "m/s"pressureUnit"hPa" | "kPa" | "inHg"aqi?number- US AQI, 0-500, from an air-quality sensor.
isDay?boolean- From sun.sun; omitted or unavailable means daylight is unknown, not day.
lastUpdated?stringlastSeen?string- While it is unavailable, when it was last reachable: the `lastSeen` option, else what Home Assistant reports.
history: WeatherHistory
Section titled “history: WeatherHistory”Today, from Home Assistant’s recorder, kept up to date by every change since. Pass history to supply your own, or
loadHistory={false} to skip the read.
temperature(number | "unavailable" | null)[]- Today's hourly temperatures so far: a value, "unavailable", or null for hours not recorded.
currentHournumber
HourlyForecast
Section titled “HourlyForecast”One hour of hourly.
hournumber- Hour of the day, 0-23 (today), 24+ for tomorrow.
temperaturenumberconditionConditionprecipitationProbability?number- Percent.
DailyForecast
Section titled “DailyForecast”One day of daily.
daystring- Short day label, e.g. "Sun".
conditionConditionhighnumberlownumberprecipitationProbability?number
Every weather entity
Section titled “Every weather entity”Hooks can’t be called in a loop, so a list renders one headless component per entity. The selector returns a string: useHaSelector re-renders only when its value changes, and a string of ids changes only when an entity comes or goes. Lists skip each item’s history read with loadHistory={false}.
import { HaWeather, useHaSelector } from "@dashhaus/core";import type { HaSnapshot } from "@dashhaus/core";
const weatherIds = (snapshot: HaSnapshot) => Object.keys(snapshot.entities).filter((id) => id.startsWith("weather.")).sort().join(" ");
/** Every weather entity, conditions only: each one's forecast is a read of its own, so leave it out of a list. */export function AllWeather() { const ids = useHaSelector(weatherIds).split(" ").filter(Boolean); return ( <ul> {ids.map((id) => ( <li key={id}> <HaWeather entityId={id} loadForecasts={false} loadHistory={false}> {({ entity }) => ( <> {entity.name}: {entity.state}, {entity.temperature ?? "—"} {entity.temperatureUnit} </> )} </HaWeather> </li> ))} </ul> );}The next five days
Section titled “The next five days”import { useHaWeather } from "@dashhaus/core";
/** The next days, read through weather.get_forecasts once an hour; undefined until the first read settles. */export function Forecast({ entityId }: { entityId: string }) { const { entity, daily } = useHaWeather(entityId, { loadHistory: false }); if (daily === undefined) return <p>Loading the forecast…</p>; return ( <ol aria-label={`${entity.name} forecast`}> {daily.slice(0, 5).map((day) => ( <li key={day.day}> {day.day}: {day.condition}, {day.low}–{day.high} {entity.temperatureUnit} {day.precipitationProbability != null && `, ${day.precipitationProbability}% rain`} </li> ))} </ol> );}A failed forecast read goes to onForecastError, never to the action errors: it’s a read, not something you did.
In a skin
Section titled “In a skin”Orb’s HaWeatherTile and Field’s HaWeatherModule are useHaWeather above each skin’s card. They take the hook’s
options as props, plus their own:
import { HaWeatherTile } from "@dashhaus/orb";import { HaWeatherModule } from "@dashhaus/field";
export function OrbWeather() { return <HaWeatherTile entityId="weather.home" aqiEntityId="sensor.home_aqi" aqiScale="US" sunEntityId="sun.sun" />;}
export function FieldWeather() { return <HaWeatherModule entityId="weather.home" sunEntityId="sun.sun" />;}entityIdstring- The Home Assistant entity id.
showControl?boolean- Compact only. false removes the inline reading, shows its value in its place, and makes the row open the detail sheet. Default true.
footprint?CardFootprint- Card footprint. The skin's stylesheet sets the heights; the three names are the shared vocabulary.
defaultOpen?booleandefaultAction?undefined
entityIdstring- The Home Assistant entity id.
footprint?FieldFootprintdefaultOpen?boolean- Open the detail panel on first render (stories).