Documentation Index
Fetch the complete documentation index at: https://mintlify.com/home-assistant/core/llms.txt
Use this file to discover all available pages before exploring further.
The binary sensor platform represents entities with two states: on/off, detected/not detected, open/closed, etc. Binary sensors are used for things like motion detection, door/window sensors, and occupancy detection.
Base Class
All binary sensor entities inherit from BinarySensorEntity, which is defined in homeassistant.components.binary_sensor.
from homeassistant.components.binary_sensor import BinarySensorEntity
class MyBinarySensor(BinarySensorEntity):
"""Representation of a binary sensor."""
Entity Description
Binary sensor entities can optionally use BinarySensorEntityDescription to define static metadata:
from homeassistant.components.binary_sensor import (
BinarySensorEntity,
BinarySensorEntityDescription,
BinarySensorDeviceClass,
)
BINARY_SENSOR_TYPES = [
BinarySensorEntityDescription(
key="motion",
name="Motion",
device_class=BinarySensorDeviceClass.MOTION,
),
]
Required Properties
is_on
Returns True if the binary sensor is on, False if off, or None if unknown.
@cached_property
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
return self._attr_is_on
Optional Properties
device_class
Indicates the type of binary sensor. This affects the icon displayed in the UI and what the on/off states represent.
@cached_property
def device_class(self) -> BinarySensorDeviceClass | None:
"""Return the class of this entity."""
return self._attr_device_class
Common device classes:
BATTERY - On = low, Off = normal
BATTERY_CHARGING - On = charging, Off = not charging
DOOR - On = open, Off = closed
GARAGE_DOOR - On = open, Off = closed
MOTION - On = motion detected, Off = no motion
OCCUPANCY - On = occupied, Off = not occupied
OPENING - On = open, Off = closed
PLUG - On = plugged in, Off = unplugged
PRESENCE - On = home, Off = away
PROBLEM - On = problem detected, Off = OK
SMOKE - On = smoke detected, Off = clear
WINDOW - On = open, Off = closed
State Property
The state property is final and automatically returns “on” or “off” based on is_on:
@final
@property
def state(self) -> Literal["on", "off"] | None:
"""Return the state of the binary sensor."""
if (is_on := self.is_on) is None:
return None
return STATE_ON if is_on else STATE_OFF
Example Implementation
from homeassistant.components.binary_sensor import (
BinarySensorEntity,
BinarySensorDeviceClass,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
class MotionSensor(BinarySensorEntity):
"""Representation of a motion sensor."""
_attr_device_class = BinarySensorDeviceClass.MOTION
def __init__(self, name: str, device_id: str) -> None:
"""Initialize the binary sensor."""
self._attr_name = name
self._attr_unique_id = f"{device_id}_motion"
self._attr_is_on = False
async def async_update(self) -> None:
"""Fetch new state data for the sensor."""
# Fetch data from your device/API
self._attr_is_on = await self._check_motion()
async def _check_motion(self) -> bool:
"""Check if motion is detected."""
# Your implementation here
return False
Push vs. Poll
For binary sensors that receive push updates (like webhooks or event-based systems):
class PushBinarySensor(BinarySensorEntity):
"""Binary sensor that receives push updates."""
_attr_should_poll = False
def __init__(self) -> None:
"""Initialize the sensor."""
self._attr_is_on = False
async def async_added_to_hass(self) -> None:
"""Subscribe to updates when added to Home Assistant."""
await super().async_added_to_hass()
# Subscribe to your device's events
self._unsubscribe = await self._device.subscribe(self._handle_event)
async def async_will_remove_from_hass(self) -> None:
"""Unsubscribe when removed."""
if self._unsubscribe:
self._unsubscribe()
def _handle_event(self, event) -> None:
"""Handle event from device."""
self._attr_is_on = event.state
self.async_write_ha_state()
Real-World Example
From the demo integration (homeassistant/components/demo/binary_sensor.py):
class DemoBinarySensor(BinarySensorEntity):
"""Representation of a Demo binary sensor."""
_attr_has_entity_name = True
_attr_name = None
_attr_should_poll = False
def __init__(
self,
unique_id: str,
device_name: str,
state: bool,
device_class: BinarySensorDeviceClass,
) -> None:
"""Initialize the demo sensor."""
self._unique_id = unique_id
self._state = state
self._attr_device_class = device_class
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self.unique_id)},
name=device_name,
)
@property
def unique_id(self) -> str:
"""Return the unique id."""
return self._unique_id
@property
def is_on(self) -> bool:
"""Return true if the binary sensor is on."""
return self._state
Entity Attributes
Binary sensors typically don’t have additional state attributes, but you can add them if needed:
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return additional attributes."""
return {
"last_triggered": self._last_triggered,
"sensitivity": self._sensitivity,
}
Important Notes
- Binary sensors should set
_attr_is_on rather than implementing state directly
- The
state property is final and automatically converts is_on to “on”/“off”
- Set
_attr_should_poll = False for sensors that receive push updates
- Binary sensors with
EntityCategory.CONFIG cannot be added (will raise HomeAssistantError)
- Always set a
device_class to get the appropriate icon and on/off semantics
Device Class Meanings
Each device class has specific semantics for what “on” and “off” mean:
| Device Class | On State | Off State |
|---|
| battery | Low | Normal |
| battery_charging | Charging | Not charging |
| carbon_monoxide | Detected | Clear |
| door | Open | Closed |
| garage_door | Open | Closed |
| gas | Detected | Clear |
| moisture | Wet | Dry |
| motion | Detected | Clear |
| occupancy | Occupied | Clear |
| opening | Open | Closed |
| plug | Plugged in | Unplugged |
| power | Detected | No power |
| presence | Home | Away |
| problem | Problem | OK |
| smoke | Detected | Clear |
| window | Open | Closed |
See Also