Cover
One cover.* entity: curtains, blinds, shades, shutters, awnings, windows, garage doors, doors and gates.
Quick example
Section titled “Quick example”import { useHaCover } from "@dashhaus/core";
export function CoverButtons({ entityId }: { entityId: string }) { const { entity, actions } = useHaCover(entityId); return ( <div role="group" aria-label={entity.name}> <button type="button" onClick={actions.onOpenCover}> Open </button> {entity.supportsStop && ( <button type="button" onClick={actions.onStopCover}> Stop </button> )} <button type="button" onClick={actions.onCloseCover}> Close </button> <span>{entity.position == null ? entity.state : `${entity.position}% open`}</span> </div> );}Open and close work on every cover. Stop, a position and a tilt depend on what the cover reports.
Component
Section titled “Component”<HaCover> is useHaCover 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: HaCoverResult) => ReactNode- Draws the hook's result. The component itself draws nothing.
useHaCover(entityId: string, options?: HaCoverOptions): HaCoverResultOne live cover for any UI: the mapped entity, today's history and its service actions.
It reads the cover, its area and today’s history. deviceClass is Home Assistant’s device_class, so you can draw a garage door differently from a curtain.
Options
Section titled “Options”name?string- Overrides Home Assistant's friendly name.
area?string- Overrides the area Home Assistant's registries resolve for the entity.
lastSeen?string- Overrides when the entity was last reachable, shown while it is unavailable.
history?CoverHistory- 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.
onActionError?(error: HaActionError) => void- Called with an HaActionError when an action is refused or fails.
Returns
Section titled “Returns”entityCoverEntityhistoryCoverHistoryactionsCoverHandlers
entity: CoverEntity
Section titled “entity: CoverEntity”entityIdstring- The Home Assistant entity id.
namestring- Its name: the `name` option, else Home Assistant's friendly name, else its entity id.
area?string- Its area: the `area` option, else the one Home Assistant's registries resolve; none when neither has one.
state"unavailable" | "open" | "closed" | "opening" | "closing" | "unknown"- `unknown` is reachable but not reporting where it is: an RF blind or a garage door with no sensor, which Home Assistant drives on an assumed state. It can be opened, closed and stopped, and it is never drawn as closed or as unavailable.
deviceClassCoverClassposition?number- current_position, 0-100. Omit when the cover only opens and closes.
tilt?number- current_tilt_position, 0-100, for blinds with slats.
supportsPositionbooleansupportsStopbooleansupportsTilt?booleanlastChanged?stringlastSeen?string- While it is unavailable, when it was last reachable: the `lastSeen` option, else what Home Assistant reports.
history: CoverHistory
Section titled “history: CoverHistory”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.
samplesHourSample[]- How open each hour was, 0-1; "unavailable"; null for hours ahead.
currentHournumber
actions: CoverHandlers
Section titled “actions: CoverHandlers”onOpenCover() => void- Calls `cover.open_cover`.
onCloseCover() => void- Calls `cover.close_cover`.
onStopCover() => void- Calls `cover.stop_cover`. A cover that can't stop reports `unsupported`.
onSetPosition?(position: number) => void- Only for a cover that reports a position. Calls `cover.set_cover_position`, held between 0 (closed) and 100 (open).
onSetTilt?(tilt: number) => void- Only for a cover with slats. Calls `cover.set_cover_tilt_position`, held between 0 and 100.
Every action on an unavailable entity is reported to onActionError as unsupported and never sent. A cover Home Assistant reports as unknown is not unavailable: its state is "unknown", and every action is sent.
Every cover
Section titled “Every cover”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 { HaCover, useHaSelector } from "@dashhaus/core";import type { HaSnapshot } from "@dashhaus/core";
const coverIds = (snapshot: HaSnapshot) => Object.keys(snapshot.entities).filter((id) => id.startsWith("cover.")).sort().join(" ");
/** Every cover, and a button that closes whichever are open. */export function AllCovers() { const ids = useHaSelector(coverIds).split(" ").filter(Boolean); return ( <ul> {ids.map((id) => ( <li key={id}> <HaCover entityId={id} loadHistory={false}> {({ entity, actions }) => ( <> {entity.name} ({entity.deviceClass}): {entity.state} {entity.state === "open" && ( <button type="button" onClick={actions.onCloseCover}> Close </button> )} </> )} </HaCover> </li> ))} </ul> );}Set how open it is
Section titled “Set how open it is”import { useHaCover } from "@dashhaus/core";
/** A position slider for a cover that reports one: 0 is closed, 100 open. */export function Position({ entityId }: { entityId: string }) { const { entity, actions } = useHaCover(entityId, { loadHistory: false }); const { onSetPosition } = actions; if (!onSetPosition) return <p>{entity.name} only opens and closes.</p>; return ( <label> {entity.name} <input type="range" min={0} max={100} value={entity.position ?? 0} disabled={entity.state === "unavailable"} onChange={(event) => onSetPosition(event.currentTarget.valueAsNumber)} /> </label> );}onSetPosition is absent for a cover that only opens and closes; say so rather than drawing a slider that does nothing.
In a skin
Section titled “In a skin”Orb’s HaCoverTile and Field’s HaCoverModule are useHaCover above each skin’s card. They take the hook’s
options as props, plus their own:
import { HaCoverTile } from "@dashhaus/orb";import { HaCoverModule } from "@dashhaus/field";
export function OrbCover() { return <HaCoverTile entityId="cover.living_room" footprint="compact" />;}
export function FieldCover() { return <HaCoverModule entityId="cover.living_room" />;}entityIdstring- The Home Assistant entity id.
showControl?boolean- Compact only. false removes the inline control, shows the value in its place, and makes the row open the detail sheet. The orb keeps its tap and hold actions. 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).