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 switch platform represents entities that can be turned on or off. Switches are used for outlets, wall switches, and other binary controllable devices.
Base Class
All switch entities inherit from SwitchEntity, which extends ToggleEntity. The class is defined in homeassistant.components.switch.
from homeassistant.components.switch import SwitchEntity
class MySwitch(SwitchEntity):
"""Representation of a switch."""
Entity Description
Switch entities can optionally use SwitchEntityDescription to define static metadata:
from homeassistant.components.switch import (
SwitchEntity,
SwitchEntityDescription,
SwitchDeviceClass,
)
SWITCH_TYPES = [
SwitchEntityDescription(
key="outlet",
name="Power Outlet",
device_class=SwitchDeviceClass.OUTLET,
),
]
Required Methods
turn_on
Turn the switch on.
def turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
# Your implementation here
turn_off
Turn the switch off.
def turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
# Your implementation here
Optional Properties
is_on
Return the current state of the switch.
@property
def is_on(self) -> bool | None:
"""Return true if switch is on."""
return self._attr_is_on
device_class
Indicates the type of switch.
@cached_property
def device_class(self) -> SwitchDeviceClass | None:
"""Return the class of this entity."""
return self._attr_device_class
Available device classes:
OUTLET - Power outlet
SWITCH - Generic switch
Services
The switch platform automatically registers these services:
switch.turn_on - Turn the switch on
switch.turn_off - Turn the switch off
switch.toggle - Toggle the switch state
Example Implementation
from typing import Any
from homeassistant.components.switch import (
SwitchEntity,
SwitchDeviceClass,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
class PowerSwitch(SwitchEntity):
"""Representation of a power switch."""
_attr_device_class = SwitchDeviceClass.OUTLET
def __init__(self, name: str, device_id: str) -> None:
"""Initialize the switch."""
self._attr_name = name
self._attr_unique_id = f"{device_id}_switch"
self._attr_is_on = False
def turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
# Send command to device
self._device.set_power(True)
self._attr_is_on = True
self.schedule_update_ha_state()
def turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
# Send command to device
self._device.set_power(False)
self._attr_is_on = False
self.schedule_update_ha_state()
Async Implementation
For async devices, override the async methods:
class AsyncSwitch(SwitchEntity):
"""Async switch implementation."""
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on asynchronously."""
await self._device.async_set_power(True)
self._attr_is_on = True
self.async_write_ha_state()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off asynchronously."""
await self._device.async_set_power(False)
self._attr_is_on = False
self.async_write_ha_state()
Real-World Example
From the demo integration (homeassistant/components/demo/switch.py):
class DemoSwitch(SwitchEntity):
"""Representation of a demo switch."""
_attr_has_entity_name = True
_attr_name = None
_attr_should_poll = False
def __init__(
self,
unique_id: str,
device_name: str,
state: bool,
assumed: bool,
translation_key: str | None = None,
device_class: SwitchDeviceClass | None = None,
) -> None:
"""Initialize the Demo switch."""
self._attr_assumed_state = assumed
self._attr_device_class = device_class
self._attr_translation_key = translation_key
self._attr_is_on = state
self._attr_unique_id = unique_id
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, unique_id)},
name=device_name,
)
def turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
self._attr_is_on = True
self.schedule_update_ha_state()
def turn_off(self, **kwargs: Any) -> None:
"""Turn the device off."""
self._attr_is_on = False
self.schedule_update_ha_state()
Toggle Support
Switches automatically support toggling via the inherited ToggleEntity base class:
# The toggle method is automatically available
async def async_toggle(self, **kwargs: Any) -> None:
"""Toggle the entity."""
if self.is_on:
await self.async_turn_off(**kwargs)
else:
await self.async_turn_on(**kwargs)
Assumed State
For devices where the state cannot be read:
class UnconfirmedSwitch(SwitchEntity):
"""Switch with assumed state."""
_attr_assumed_state = True
def turn_on(self, **kwargs: Any) -> None:
"""Turn on (send command but can't confirm)."""
self._device.send_on_command()
self._attr_is_on = True # Assume it worked
self.schedule_update_ha_state()
Optimistic Updates
For fast UI response while waiting for device confirmation:
class OptimisticSwitch(SwitchEntity):
"""Switch with optimistic updates."""
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
# Update state immediately for UI
self._attr_is_on = True
self.async_write_ha_state()
# Send command to device
await self._device.async_set_power(True)
# Refresh state from device to confirm
await self.async_update()
Important Notes
- Always call
schedule_update_ha_state() (sync) or async_write_ha_state() (async) after changing state
- Switches inherit from
ToggleEntity, which provides the toggle functionality
- Set
_attr_should_poll = False for switches that receive push updates
- Use
_attr_assumed_state = True when you can’t read back the actual state
- The
turn_on and turn_off methods should update _attr_is_on to reflect the new state
State Management
Switches can manage state in different ways:
Polling (Default)
class PollingSwitch(SwitchEntity):
"""Switch that polls for state."""
async def async_update(self) -> None:
"""Fetch state from device."""
self._attr_is_on = await self._device.get_state()
Push Updates
class PushSwitch(SwitchEntity):
"""Switch that receives push updates."""
_attr_should_poll = False
async def async_added_to_hass(self) -> None:
"""Subscribe to updates."""
await super().async_added_to_hass()
self._device.subscribe(self._handle_update)
def _handle_update(self, state: bool) -> None:
"""Handle state update from device."""
self._attr_is_on = state
self.async_write_ha_state()
See Also