Climate
Control thermostats and HVAC systems: target temperature, mode, fan, and presets.
Quick Example
// Component approach
<Climate entityId="climate.living_room">
{({ currentTemperature, targetTemperature, mode, setMode, setTemperature }) => (
<div>
<p>Current: {currentTemperature}°F</p>
<p>Target: {targetTemperature}°F</p>
<button onClick={() => setMode(mode === 'heat' ? 'off' : 'heat')}>
Mode: {mode}
</button>
</div>
)}
</Climate>
// Hook approach
const thermostat = useClimate('climate.living_room')
<div>
<p>Current: {thermostat.currentTemperature}°F</p>
<button onClick={() => thermostat.setTemperature(72)}>
Set to 72°F
</button>
</div>
Component API
Basic Usage
import { Climate } from 'hass-react'
<Climate entityId="climate.living_room">
{(climateProps) => (
// Your UI here
)}
</Climate>
Render Props
The Climate component provides these props to your render function:
State Properties
currentTemperature(number | undefined) - Current temperature readingtargetTemperature(number | undefined) - Target temperature settingtargetTempHigh(number | undefined) - High target for heat/cool modetargetTempLow(number | undefined) - Low target for heat/cool modehumidity(number | undefined) - Current humidity percentagemode(string) - Current HVAC mode (heat, cool, auto, off, etc.)fanMode(string | undefined) - Current fan mode (auto, on, low, etc.)presetMode(string | undefined) - Current preset mode (away, home, sleep, etc.)
Support Properties
supportsTargetTemperature(boolean) - Device supports setting target temperaturesupportsTargetTemperatureRange(boolean) - Device supports temperature rangesupportsFanMode(boolean) - Device supports fan mode controlsupportsPresetMode(boolean) - Device supports preset modessupportedModes(string[]) - List of available HVAC modessupportedFanModes(string[]) - List of available fan modessupportedPresetModes(string[]) - List of available preset modesminTemp(number) - Minimum supported temperature. If the device doesn't report one, falls back to 45°F or 7°C depending on the entity's temperature unitmaxTemp(number) - Maximum supported temperature. Falls back to 95°F or 35°C the same way
Control Methods
setMode(mode: string)- Set HVAC mode (heat, cool, auto, off, etc.)setTemperature(temp: number)- Set target temperaturesetTemperatureRange(low: number, high: number)- Set temperature rangesetFanMode(mode: string)- Set fan modesetPresetMode(preset: string)- Set preset mode
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 { useClimate } from 'hass-react'
function MyComponent() {
const climate = useClimate('climate.living_room')
// All the same properties as component render props
return <div>Mode: {climate.mode} - {climate.currentTemperature}°F</div>
}
useClimate returns the same properties and methods as the component's render props.
List All Climate Devices
The useClimates hook returns every climate entity Home Assistant knows about:
import { useClimates } from 'hass-react'
function ClimateList() {
const climates = useClimates()
return (
<div>
<h2>Available Climate Devices ({climates.length})</h2>
{climates.map(climate => (
<div key={climate.entity_id}>
{climate.attributes.friendly_name || climate.entity_id}
</div>
))}
</div>
)
}
It returns an array of climate entity objects, one per device.
Examples
Simple Thermostat
<Climate entityId="climate.main_floor">
{({
currentTemperature, targetTemperature, mode,
setMode, setTemperature, supportsTargetTemperature,
supportedModes, minTemp, maxTemp, attributes
}) => (
<div>
<h3>{attributes.friendly_name}</h3>
<div>
<strong>Current: {currentTemperature}°F</strong>
{supportsTargetTemperature && (
<p>Target: {targetTemperature}°F</p>
)}
</div>
<div>
<label>Mode:</label>
<select value={mode} onChange={(e) => setMode(e.target.value)}>
{supportedModes.map(modeOption => (
<option key={modeOption} value={modeOption}>
{modeOption.charAt(0).toUpperCase() + modeOption.slice(1)}
</option>
))}
</select>
</div>
{supportsTargetTemperature && mode !== 'off' && (
<div>
<label>Temperature: {targetTemperature}°F</label>
<input
type="range"
min={minTemp}
max={maxTemp}
value={targetTemperature || minTemp}
onChange={(e) => setTemperature(parseInt(e.target.value))}
/>
</div>
)}
</div>
)}
</Climate>
Temperature Range Control
<Climate entityId="climate.bedroom">
{({
currentTemperature, targetTempLow, targetTempHigh, mode,
setMode, setTemperatureRange, supportsTargetTemperatureRange,
supportedModes, minTemp, maxTemp, attributes
}) => (
<div>
<h3>{attributes.friendly_name}</h3>
<p>Current: {currentTemperature}°F</p>
<div>
<label>Mode:</label>
<select value={mode} onChange={(e) => setMode(e.target.value)}>
{supportedModes.map(modeOption => (
<option key={modeOption} value={modeOption}>
{modeOption.charAt(0).toUpperCase() + modeOption.slice(1)}
</option>
))}
</select>
</div>
{supportsTargetTemperatureRange && mode === 'heat_cool' && (
<div>
<div>
<label>Low: {targetTempLow}°F</label>
<input
type="range"
min={minTemp}
max={maxTemp}
value={targetTempLow || minTemp}
onChange={(e) => setTemperatureRange(
parseInt(e.target.value),
targetTempHigh || maxTemp
)}
/>
</div>
<div>
<label>High: {targetTempHigh}°F</label>
<input
type="range"
min={minTemp}
max={maxTemp}
value={targetTempHigh || maxTemp}
onChange={(e) => setTemperatureRange(
targetTempLow || minTemp,
parseInt(e.target.value)
)}
/>
</div>
</div>
)}
</div>
)}
</Climate>
Full Featured Control
<Climate entityId="climate.master_bedroom">
{({
currentTemperature, targetTemperature, humidity, mode, fanMode, presetMode,
supportsTargetTemperature, supportsFanMode, supportsPresetMode,
supportedModes, supportedFanModes, supportedPresetModes,
setMode, setTemperature, setFanMode, setPresetMode,
minTemp, maxTemp, attributes
}) => (
<div>
<h3>{attributes.friendly_name}</h3>
<div>
<div>
<strong>Current Temp</strong>
<p>{currentTemperature}°F</p>
</div>
{supportsTargetTemperature && (
<div>
<strong>Target Temp</strong>
<p>{targetTemperature}°F</p>
</div>
)}
{humidity !== undefined && (
<div>
<strong>Humidity</strong>
<p>{humidity}%</p>
</div>
)}
</div>
<div>
<label>HVAC Mode:</label>
<select value={mode} onChange={(e) => setMode(e.target.value)}>
{supportedModes.map(modeOption => (
<option key={modeOption} value={modeOption}>
{modeOption.charAt(0).toUpperCase() + modeOption.slice(1)}
</option>
))}
</select>
</div>
{supportsTargetTemperature && mode !== 'off' && (
<div>
<label>Temperature: {targetTemperature}°F</label>
<input
type="range"
min={minTemp}
max={maxTemp}
value={targetTemperature || minTemp}
onChange={(e) => setTemperature(parseInt(e.target.value))}
/>
<div>
<span>{minTemp}°F</span>
<span>{maxTemp}°F</span>
</div>
</div>
)}
{supportsFanMode && supportedFanModes.length > 0 && (
<div>
<label>Fan Mode:</label>
<select value={fanMode || ''} onChange={(e) => setFanMode(e.target.value)}>
{supportedFanModes.map(fan => (
<option key={fan} value={fan}>
{fan.charAt(0).toUpperCase() + fan.slice(1)}
</option>
))}
</select>
</div>
)}
{supportsPresetMode && supportedPresetModes.length > 0 && (
<div>
<label>Preset:</label>
<select value={presetMode || ''} onChange={(e) => setPresetMode(e.target.value)}>
<option value="">None</option>
{supportedPresetModes.map(preset => (
<option key={preset} value={preset}>
{preset.charAt(0).toUpperCase() + preset.slice(1)}
</option>
))}
</select>
</div>
)}
</div>
)}
</Climate>
Quick Temperature Controls
<Climate entityId="climate.office">
{({
currentTemperature, targetTemperature, mode,
setTemperature, setMode, supportsTargetTemperature,
attributes
}) => {
const quickTemps = [68, 70, 72, 74, 76]
return (
<div>
<h3>{attributes.friendly_name}</h3>
<div>
<p>Current: {currentTemperature}°F</p>
<p>Target: {targetTemperature}°F</p>
<p>Mode: {mode}</p>
</div>
<button onClick={() => setMode(mode === 'off' ? 'heat' : 'off')}>
{mode === 'off' ? 'Turn On' : 'Turn Off'}
</button>
{supportsTargetTemperature && mode !== 'off' && (
<div>
<p>Quick Set:</p>
<div>
{quickTemps.map(temp => (
<button
key={temp}
onClick={() => setTemperature(temp)}
>
{temp}°F
</button>
))}
</div>
</div>
)}
</div>
)
}}
</Climate>
Using Hooks
import { useClimate } from 'hass-react'
function ThermostatCard({ entityId }) {
const climate = useClimate(entityId)
return (
<div>
<h3>{climate.attributes.friendly_name}</h3>
<div>
<div>
<strong>{climate.currentTemperature}°F</strong>
<div>Current</div>
</div>
{climate.supportsTargetTemperature && (
<div>
<strong>{climate.targetTemperature}°F</strong>
<div>Target</div>
</div>
)}
<div>
<strong>{climate.mode}</strong>
<div>Mode</div>
</div>
</div>
<div>
<button
onClick={() => climate.setMode('heat')}
disabled={climate.mode === 'heat'}
>
Heat
</button>
<button
onClick={() => climate.setMode('cool')}
disabled={climate.mode === 'cool'}
>
Cool
</button>
<button
onClick={() => climate.setMode('off')}
disabled={climate.mode === 'off'}
>
Off
</button>
</div>
{climate.supportsTargetTemperature && climate.mode !== 'off' && (
<div>
<button onClick={() => climate.setTemperature((climate.targetTemperature || 70) - 1)}>
-
</button>
<span>{climate.targetTemperature}°F</span>
<button onClick={() => climate.setTemperature((climate.targetTemperature || 70) + 1)}>
+
</button>
</div>
)}
</div>
)
}