Sun
Home Assistant’s sun.sun, from its Sun integration: whether the sun is up, and when it next sets, rises, dawns,
dusks and peaks. With your home’s location, today’s path of the sun too. Read-only.
Quick example
Section titled “Quick example”import { useHaSun } from "@dashhaus/core";import { useHourCycle } from "@dashhaus/core/hooks";import { sunAllDay, sunNext, sunTime, sunWhen } from "@dashhaus/core/entities/sun/words";
/** When the sun next sets or rises, on the page's clock, and how long until it. */export function NextSunEvent() { const { entity } = useHaSun("sun.sun"); const hourCycle = useHourCycle(); if (entity.state === "unavailable") return <p>{entity.name} is unavailable</p>; const next = sunNext(entity); if (!next) return <p>{sunAllDay(entity) ?? "Waiting…"}</p>; return <p>{sunTime(next, hourCycle)}: {sunWhen(next, entity.now)}</p>;}sunNext is what a card leads with: the sunset while the sun is up, the sunrise while it is down. sunWhen counts down
to it from the entity’s own minute: Sets in 4h 35m, Rises in 9m, or its day when it is more than a day off
(Rises Thu). Where neither comes within two days, as in a polar summer or winter, sunAllDay says Up all day or
Down all day. Times are on the page’s clock: 20:30, or on a 12-hour page 8:30 PM (pass sunTime the page’s
useHourCycle()). Every skin says it in these words.
Component
Section titled “Component”<HaSun> is useHaSun 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: HaSunResult) => ReactNode- Draws the hook's result. The component itself draws nothing.
useHaSun(entityId: string, options?: HaSunOptions): HaSunResultThe sun for any UI: the mapped `sun.*` entity, counted from the minute clock, and today's path, worked out from the home's latitude and longitude (Home Assistant's `get_config`, read once per connection, or the options). It sends no services.
It reads the sun and counts from a clock that turns each minute. Today’s path is worked out from your home’s latitude
and longitude, read once from Home Assistant’s configuration; pass latitude and longitude to draw it for another
place, or loadHistory: false to leave it out.
Options
Section titled “Options”name?string- Overrides Home Assistant's friendly name.
area?string- Overrides the area Home Assistant's registries resolve.
lastSeen?string- Overrides when the entity was last reachable, shown while it is unavailable.
latitude?number- Where today's path is drawn from, in degrees; by default Home Assistant's own location (`get_config`).
longitude?numberloadHistory?boolean- Set false to leave out today's path (YAML `history: false`): `history` is then undefined.
Returns
Section titled “Returns”entitySunEntityhistorySunHistory | undefined- Today's path of the sun, worked out from the location: no recorder read. Undefined without a location, or with `loadHistory: false`.
entity: SunEntity
Section titled “entity: SunEntity”entityIdstringnamestring- The entity's name: "Sun".
area?string- Its area: the `area` option, else the one Home Assistant's registries resolve; the sun usually has none.
state"unavailable" | "ok"- "unavailable" while it can't be read (`unknown`, `unavailable`, missing); "ok" otherwise.
up?boolean- Above the horizon (`above_horizon`); omitted while it isn't known. Its active set (`isActive`).
nextRising?number- When it next rises and sets (`next_rising`, `next_setting`); omitted until Home Assistant reports them.
nextSetting?numbernextDawn?number- When civil twilight next begins and ends (`next_dawn`, `next_dusk`), and the sun next peaks (`next_noon`).
nextDusk?numbernextNoon?numberelevation?number- Its height above the horizon, in degrees (`elevation`): below zero at night.
azimuth?number- Its compass bearing, in degrees from north (`azimuth`).
nownumber- The minute the card counts from, in ms since the epoch: the hook's minute clock, or a seed's fixed minute. "Sets in 4h 35m" and where the sun is drawn on today's path are counted from it.
lastUpdated?string- When Home Assistant last updated it ("11:54").
lastSeen?string- While it is unavailable, when it was last reachable.
history: SunHistory
Section titled “history: SunHistory”Today’s path of the sun from midnight to midnight, worked out from the location rather than read from Home Assistant’s recorder: its elevation through the day, each hour’s height against the day’s peak, where now, sunrise and sunset fall, and how long it is up.
pathnumber[]- The sun's elevation in degrees, `SUN_PATH_STEPS + 1` points evenly spaced over the local day.
samplesHourSample[]- Per hour, 0 to 1: the sun's highest elevation in that hour against the day's peak; 0 while it is down.
currentHournumbernowAtnumber- Where now falls in the day, 0 to 1.
riseAt?number- Where today's sunrise and sunset fall in the day, 0 to 1; omitted on a day it doesn't rise or set.
setAt?numberrise?number- When today's sunrise and sunset are, in ms since the epoch, from the path; omitted with `riseAt` and `setAt`.
set?numberpeaknumber- Today's highest elevation, in degrees.
daylightMinutesnumber- Minutes the sun is up today.
Today’s path
Section titled “Today’s path”sunPathDrawing turns the path into pieces of line for any drawing: the day so far, the day still to come and the
night, the horizon and where the sun is now, all as fractions of the drawing.
import { useHaSun } from "@dashhaus/core";import { sunPathDrawing } from "@dashhaus/core/entities/sun/drawing";import { daylightSummary } from "@dashhaus/core/entities/sun/words";
/** Today's path of the sun as a line, the day so far solid and the rest dotted, with the sun on it. */export function SunPath() { const { history } = useHaSun("sun.sun"); if (!history) return null; const drawing = sunPathDrawing(history); const [x, y] = drawing.sun; return ( <figure> <svg viewBox="0 0 1 1" preserveAspectRatio="none" width={240} height={80}> {drawing.pieces.map((piece, i) => ( <polyline key={i} points={piece.points.map(([px, py]) => `${px},${py}`).join(" ")} fill="none" stroke="currentColor" strokeWidth={piece.part === "past" ? 2 : 1} strokeDasharray={piece.part === "past" ? undefined : "2 3"} vectorEffect="non-scaling-stroke" /> ))} <circle cx={x} cy={y} r={0.02} fill="currentColor" /> </svg> <figcaption>{daylightSummary(history)}</figcaption> </figure> );}In a skin
Section titled “In a skin”Orb’s HaSunTile and Field’s HaSunModule are useHaSun above each skin’s card. Each leads with what comes next and
counts down to it, draws today’s path (Orb’s as a line with the sun on it, Field’s as the sun’s height by hour), and
opens on every time to come. They take the hook’s options as props, plus their own:
import { HaSunTile } from "@dashhaus/orb";import { HaSunModule } from "@dashhaus/field";
/** The sun with today's path, from Home Assistant's own location. */export function OrbSun() { return <HaSunTile entityId="sun.sun" footprint="featured" />;}
/** The same as a compact row: the countdown on the row's line, the time on the screen. */export function FieldSun() { return <HaSunModule entityId="sun.sun" footprint="compact" />;}entityIdstringshowControl?boolean- Compact only. false removes the inline control, shows the value in its place, and makes the row open the details. Default true.
footprint?CardFootprint- Card footprint. The skin's stylesheet sets the heights; the three names are the shared vocabulary.
defaultOpen?booleandefaultAction?undefined
entityIdstringfootprint?FieldFootprintdefaultOpen?boolean- Open the detail panel on first render (stories).