> ## 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.

# Binary Sensor Platform

> API reference for implementing binary sensor entities in Home Assistant

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`.

```python theme={null}
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:

```python theme={null}
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.

```python theme={null}
@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.

```python theme={null}
@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`:

```python theme={null}
@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

```python theme={null}
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):

```python theme={null}
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`):

```python theme={null}
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:

```python theme={null}
@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

* [Entity Documentation](/api/entity)
* [Binary Sensor Device Classes](https://github.com/home-assistant/core/blob/dev/homeassistant/components/binary_sensor/__init__.py)
* [Demo Binary Sensor Implementation](https://github.com/home-assistant/core/blob/dev/homeassistant/components/demo/binary_sensor.py)
