Cover
Control covers, blinds, garage doors, curtains, and shades.
Quick Example
// Component approach
<Cover entityId="cover.garage_door">
{({ isOpen, isClosed, open, close }) => (
<div>
<p>Garage: {isOpen ? 'OPEN' : isClosed ? 'CLOSED' : 'PARTIAL'}</p>
<button onClick={isOpen ? close : open}>
{isOpen ? 'Close' : 'Open'}
</button>
</div>
)}
</Cover>
// Hook approach
const garage = useCover('cover.garage_door')
<div>
<p>Garage: {garage.isOpen ? 'OPEN' : garage.isClosed ? 'CLOSED' : 'PARTIAL'}</p>
<button onClick={garage.isOpen ? garage.close : garage.open}>
{garage.isOpen ? 'Close' : 'Open'}
</button>
</div>
Component API
Basic Usage
import { Cover } from 'hass-react'
<Cover entityId="cover.garage_door">
{(coverProps) => (
// Your UI here
)}
</Cover>
Render Props
The Cover component provides these props to your render function:
State Properties
isOpen(boolean) - Whether the cover is fully openisClosed(boolean) - Whether the cover is fully closedisOpening(boolean) - Whether the cover is currently openingisClosing(boolean) - Whether the cover is currently closingposition(number | undefined) - Current position (0-100, where 0 is closed and 100 is open)
Control Methods
open()- Open the cover completelyclose()- Close the cover completelystop()- Stop the cover movementsetPosition(position: number)- Set cover to specific position (0-100)
Entity Properties
entityId(string) - The entity IDstate(string) - Raw state value from Home Assistantattributes(object) - All entity attributeslastChanged(Date) - When the entity last changedlastUpdated(Date) - When the entity was last updated
Hook API
Basic Usage
import { useCover } from 'hass-react'
function MyComponent() {
const cover = useCover('cover.garage_door')
// All the same properties as component render props
return <div>{cover.isOpen ? 'OPEN' : 'CLOSED'}</div>
}
The useCover hook returns an object with all the same properties and methods as the component's render props.
List All Covers
Use the useCovers hook to retrieve all available cover entities:
import { useCovers } from 'hass-react'
function CoverList() {
const covers = useCovers()
return (
<div>
<h2>Available Covers ({covers.length})</h2>
{covers.map(cover => (
<div key={cover.entity_id}>
{cover.attributes.friendly_name || cover.entity_id}
</div>
))}
</div>
)
}
The useCovers hook fetches all cover entities from Home Assistant and returns an array of cover objects.
Examples
Simple Cover Control
<Cover entityId="cover.living_room_blinds">
{({ isOpen, isClosed, isOpening, isClosing, open, close, stop, attributes }) => (
<div>
<h3>{attributes.friendly_name}</h3>
<p>
Status: {
isOpening ? 'OPENING' :
isClosing ? 'CLOSING' :
isOpen ? 'OPEN' :
isClosed ? 'CLOSED' : 'PARTIAL'
}
</p>
<button onClick={open} disabled={isOpen || isOpening}>
Open
</button>
<button onClick={close} disabled={isClosed || isClosing}>
Close
</button>
{(isOpening || isClosing) && (
<button onClick={stop}>
Stop
</button>
)}
</div>
)}
</Cover>
Position Control
<Cover entityId="cover.bedroom_shades">
{({ position, setPosition, isOpening, isClosing, attributes }) => (
<div>
<h3>{attributes.friendly_name}</h3>
<p>Position: {position !== undefined ? `${position}%` : 'Unknown'}</p>
{position !== undefined && (
<div>
<input
type="range"
min="0"
max="100"
value={position}
onChange={(e) => setPosition(parseInt(e.target.value))}
disabled={isOpening || isClosing}
/>
<div>
<button onClick={() => setPosition(0)}>
Fully Closed
</button>
<button onClick={() => setPosition(25)}>
25%
</button>
<button onClick={() => setPosition(50)}>
50%
</button>
<button onClick={() => setPosition(75)}>
75%
</button>
<button onClick={() => setPosition(100)}>
Fully Open
</button>
</div>
</div>
)}
</div>
)}
</Cover>
Garage Door Control
<Cover entityId="cover.garage_door">
{({ isOpen, isClosed, isOpening, isClosing, open, close, stop, attributes, lastChanged }) => (
<div>
<h3>{attributes.friendly_name}</h3>
<div>
Status: {
isOpening ? 'OPENING' :
isClosing ? 'CLOSING' :
isOpen ? 'OPEN' :
isClosed ? 'CLOSED' : 'UNKNOWN'
}
</div>
<div>
<button
onClick={isOpen ? close : open}
disabled={isOpening || isClosing}
>
{isOpen ? 'Close Garage' : 'Open Garage'}
</button>
{(isOpening || isClosing) && (
<button onClick={stop}>
Emergency Stop
</button>
)}
</div>
{isOpen && (
<p style={{ color: 'orange' }}>
Warning: Garage door is open
</p>
)}
<p>Last changed: {lastChanged.toLocaleString()}</p>
</div>
)}
</Cover>
Multiple Covers
function CoverPanel() {
const covers = [
'cover.living_room_blinds',
'cover.bedroom_shades',
'cover.kitchen_curtains'
]
return (
<div>
<h2>Window Coverings</h2>
{covers.map(entityId => (
<Cover key={entityId} entityId={entityId}>
{({ isOpen, isClosed, position, open, close, attributes }) => (
<div>
<strong>{attributes.friendly_name}</strong>
<br />
Status: {isOpen ? 'OPEN' : isClosed ? 'CLOSED' : 'PARTIAL'}
{position !== undefined && ` (${position}%)`}
<br />
<button onClick={open} disabled={isOpen}>
Open
</button>
<button onClick={close} disabled={isClosed}>
Close
</button>
</div>
)}
</Cover>
))}
</div>
)
}
Smart Blinds with Scheduling
<Cover entityId="cover.office_blinds">
{({ position, setPosition, attributes }) => {
const [autoMode, setAutoMode] = useState(false)
useEffect(() => {
if (!autoMode) return
const now = new Date()
const hour = now.getHours()
// Auto-adjust based on time of day
if (hour >= 6 && hour < 9) {
// Morning: 25% open
setPosition(25)
} else if (hour >= 9 && hour < 17) {
// Daytime: 75% open
setPosition(75)
} else if (hour >= 17 && hour < 20) {
// Evening: 50% open
setPosition(50)
} else {
// Night: Closed
setPosition(0)
}
}, [autoMode, setPosition])
return (
<div>
<h3>{attributes.friendly_name}</h3>
<p>Position: {position !== undefined ? `${position}%` : 'Unknown'}</p>
<div>
<label>
<input
type="checkbox"
checked={autoMode}
onChange={(e) => setAutoMode(e.target.checked)}
/>
Auto-scheduling
</label>
</div>
{!autoMode && position !== undefined && (
<input
type="range"
min="0"
max="100"
value={position}
onChange={(e) => setPosition(parseInt(e.target.value))}
/>
)}
</div>
)
}}
</Cover>
Cover Status Indicator
<Cover entityId="cover.patio_awning">
{({ isOpen, isClosed, isOpening, isClosing, position, attributes }) => {
const getStatusColor = () => {
if (isOpening || isClosing) return 'blue'
if (isOpen) return 'green'
if (isClosed) return 'gray'
return 'orange'
}
const getStatusText = () => {
if (isOpening) return 'OPENING...'
if (isClosing) return 'CLOSING...'
if (isOpen) return 'OPEN'
if (isClosed) return 'CLOSED'
return 'PARTIAL'
}
return (
<div>
<h3>{attributes.friendly_name}</h3>
<div style={{ color: getStatusColor() }}>
Status: {getStatusText()}
{position !== undefined && ` (${position}%)`}
</div>
{position !== undefined && (
<div>
Progress: {position}%
</div>
)}
</div>
)
}}
</Cover>
Using Hooks
import { useCover } from 'hass-react'
function CoverCard({ entityId }) {
const cover = useCover(entityId)
const getStatusDisplay = () => {
if (cover.isOpening) return { text: 'OPENING', color: 'blue' }
if (cover.isClosing) return { text: 'CLOSING', color: 'blue' }
if (cover.isOpen) return { text: 'OPEN', color: 'green' }
if (cover.isClosed) return { text: 'CLOSED', color: 'gray' }
return { text: 'PARTIAL', color: 'orange' }
}
const status = getStatusDisplay()
return (
<div>
<h3>{cover.attributes.friendly_name}</h3>
<div style={{ color: status.color }}>
Status: {status.text}
{cover.position !== undefined && ` (${cover.position}%)`}
</div>
<div>
<button
onClick={cover.open}
disabled={cover.isOpen || cover.isOpening}
>
Open
</button>
<button
onClick={cover.close}
disabled={cover.isClosed || cover.isClosing}
>
Close
</button>
{(cover.isOpening || cover.isClosing) && (
<button onClick={cover.stop}>
Stop
</button>
)}
</div>
{cover.position !== undefined && (
<div>
<input
type="range"
min="0"
max="100"
value={cover.position}
onChange={(e) => cover.setPosition(parseInt(e.target.value))}
disabled={cover.isOpening || cover.isClosing}
/>
</div>
)}
<p>Last updated: {cover.lastUpdated.toLocaleTimeString()}</p>
</div>
)
}