core/homeassistant/components/flux_led/switch.py

140 lines
4.8 KiB
Python

"""Support for Magic Home switches."""
from __future__ import annotations
from typing import Any
from flux_led import DeviceType
from flux_led.aio import AIOWifiLedBulb
from flux_led.const import MODE_MUSIC
from homeassistant import config_entries
from homeassistant.components.switch import SwitchEntity
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import (
CONF_REMOTE_ACCESS_ENABLED,
CONF_REMOTE_ACCESS_HOST,
CONF_REMOTE_ACCESS_PORT,
DOMAIN,
)
from .coordinator import FluxLedUpdateCoordinator
from .discovery import async_clear_discovery_cache
from .entity import FluxBaseEntity, FluxEntity, FluxOnOffEntity
async def async_setup_entry(
hass: HomeAssistant,
entry: config_entries.ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Flux lights."""
coordinator: FluxLedUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
entities: list[FluxSwitch | FluxRemoteAccessSwitch | FluxMusicSwitch] = []
base_unique_id = entry.unique_id or entry.entry_id
name = entry.data.get(CONF_NAME, entry.title)
if coordinator.device.device_type == DeviceType.Switch:
entities.append(FluxSwitch(coordinator, base_unique_id, name, None))
if entry.data.get(CONF_REMOTE_ACCESS_HOST):
entities.append(FluxRemoteAccessSwitch(coordinator.device, entry))
if coordinator.device.microphone:
entities.append(
FluxMusicSwitch(coordinator, base_unique_id, f"{name} Music", "music")
)
if entities:
async_add_entities(entities)
class FluxSwitch(
FluxOnOffEntity, CoordinatorEntity[FluxLedUpdateCoordinator], SwitchEntity
):
"""Representation of a Flux switch."""
async def _async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on."""
if not self.is_on:
await self._device.async_turn_on()
class FluxRemoteAccessSwitch(FluxBaseEntity, SwitchEntity):
"""Representation of a Flux remote access switch."""
_attr_entity_category = EntityCategory.CONFIG
def __init__(
self,
device: AIOWifiLedBulb,
entry: config_entries.ConfigEntry,
) -> None:
"""Initialize the light."""
super().__init__(device, entry)
self._attr_name = f"{entry.data.get(CONF_NAME, entry.title)} Remote Access"
base_unique_id = entry.unique_id or entry.entry_id
self._attr_unique_id = f"{base_unique_id}_remote_access"
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the remote access on."""
await self._device.async_enable_remote_access(
self.entry.data[CONF_REMOTE_ACCESS_HOST],
self.entry.data[CONF_REMOTE_ACCESS_PORT],
)
await self._async_update_entry(True)
async def _async_update_entry(self, new_state: bool) -> None:
"""Update the entry with the new state on success."""
async_clear_discovery_cache(self.hass, self._device.ipaddr)
self.hass.config_entries.async_update_entry(
self.entry,
data={**self.entry.data, CONF_REMOTE_ACCESS_ENABLED: new_state},
)
self.async_write_ha_state()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the remote access off."""
await self._device.async_disable_remote_access()
await self._async_update_entry(False)
@property
def is_on(self) -> bool:
"""Return true if remote access is enabled."""
return bool(self.entry.data[CONF_REMOTE_ACCESS_ENABLED])
@property
def icon(self) -> str:
"""Return icon based on state."""
return "mdi:cloud-outline" if self.is_on else "mdi:cloud-off-outline"
class FluxMusicSwitch(FluxEntity, SwitchEntity):
"""Representation of a Flux music switch."""
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the microphone on."""
await self._async_ensure_device_on()
await self._device.async_set_music_mode()
self.async_write_ha_state()
await self.coordinator.async_request_refresh()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the microphone off."""
await self._device.async_set_levels(*self._device.rgb, brightness=255)
self.async_write_ha_state()
await self.coordinator.async_request_refresh()
@property
def is_on(self) -> bool:
"""Return true if microphone is is on."""
return self._device.is_on and self._device.effect == MODE_MUSIC
@property
def icon(self) -> str:
"""Return icon based on state."""
return "mdi:microphone" if self.is_on else "mdi:microphone-off"