Use entity class vars in WLED ()

This commit is contained in:
Franck Nijhof 2021-05-26 14:08:09 +02:00 committed by GitHub
parent 5a5a145778
commit bf13af34b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 117 additions and 263 deletions
homeassistant/components/wled
tests/components/wled

View file

@ -131,42 +131,6 @@ class WLEDEntity(CoordinatorEntity):
coordinator: WLEDDataUpdateCoordinator
def __init__(
self,
*,
entry_id: str,
coordinator: WLEDDataUpdateCoordinator,
name: str,
icon: str,
enabled_default: bool = True,
) -> None:
"""Initialize the WLED entity."""
super().__init__(coordinator)
self._enabled_default = enabled_default
self._entry_id = entry_id
self._icon = icon
self._name = name
self._unsub_dispatcher = None
@property
def name(self) -> str:
"""Return the name of the entity."""
return self._name
@property
def icon(self) -> str:
"""Return the mdi icon of the entity."""
return self._icon
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._enabled_default
class WLEDDeviceEntity(WLEDEntity):
"""Defines a WLED device entity."""
@property
def device_info(self) -> DeviceInfo:
"""Return device information about this WLED device."""

View file

@ -30,7 +30,7 @@ from homeassistant.helpers.entity_registry import (
)
import homeassistant.util.color as color_util
from . import WLEDDataUpdateCoordinator, WLEDDeviceEntity, wled_exception_handler
from . import WLEDDataUpdateCoordinator, WLEDEntity, wled_exception_handler
from .const import (
ATTR_COLOR_PRIMARY,
ATTR_INTENSITY,
@ -93,27 +93,17 @@ async def async_setup_entry(
update_segments()
class WLEDMasterLight(LightEntity, WLEDDeviceEntity):
class WLEDMasterLight(WLEDEntity, LightEntity):
"""Defines a WLED master light."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_supported_features = SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION
_attr_icon = "mdi:led-strip-variant"
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED master light."""
super().__init__(
entry_id=entry_id,
coordinator=coordinator,
name=f"{coordinator.data.info.name} Master",
icon="mdi:led-strip-variant",
)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return f"{self.coordinator.data.info.mac_address}"
@property
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_BRIGHTNESS | SUPPORT_TRANSITION
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Master"
self._attr_unique_id = coordinator.data.info.mac_address
@property
def brightness(self) -> int | None:
@ -172,33 +162,26 @@ class WLEDMasterLight(LightEntity, WLEDDeviceEntity):
await self.coordinator.wled.preset(**data)
class WLEDSegmentLight(LightEntity, WLEDDeviceEntity):
class WLEDSegmentLight(WLEDEntity, LightEntity):
"""Defines a WLED light based on a segment."""
def __init__(
self, entry_id: str, coordinator: WLEDDataUpdateCoordinator, segment: int
) -> None:
_attr_icon = "mdi:led-strip-variant"
def __init__(self, coordinator: WLEDDataUpdateCoordinator, segment: int) -> None:
"""Initialize WLED segment light."""
super().__init__(coordinator=coordinator)
self._rgbw = coordinator.data.info.leds.rgbw
self._segment = segment
# If this is the one and only segment, use a simpler name
name = f"{coordinator.data.info.name} Segment {self._segment}"
self._attr_name = f"{coordinator.data.info.name} Segment {segment}"
if len(coordinator.data.state.segments) == 1:
name = coordinator.data.info.name
self._attr_name = coordinator.data.info.name
super().__init__(
entry_id=entry_id,
coordinator=coordinator,
name=name,
icon="mdi:led-strip-variant",
self._attr_unique_id = (
f"{self.coordinator.data.info.mac_address}_{self._segment}"
)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return f"{self.coordinator.data.info.mac_address}_{self._segment}"
@property
def available(self) -> bool:
"""Return True if entity is available."""
@ -436,12 +419,12 @@ def async_update_segments(
# Process new segments, add them to Home Assistant
new_entities = []
for segment_id in segment_ids - current_ids:
current[segment_id] = WLEDSegmentLight(entry.entry_id, coordinator, segment_id)
current[segment_id] = WLEDSegmentLight(coordinator, segment_id)
new_entities.append(current[segment_id])
# More than 1 segment now? Add master controls
if len(current_ids) < 2 and len(segment_ids) > 1:
current[-1] = WLEDMasterLight(entry.entry_id, coordinator)
current[-1] = WLEDMasterLight(coordinator)
new_entities.append(current[-1])
if new_entities:

View file

@ -17,7 +17,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.dt import utcnow
from . import WLEDDataUpdateCoordinator, WLEDDeviceEntity
from . import WLEDDataUpdateCoordinator, WLEDEntity
from .const import ATTR_LED_COUNT, ATTR_MAX_POWER, CURRENT_MA, DOMAIN
@ -30,68 +30,30 @@ async def async_setup_entry(
coordinator: WLEDDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
sensors = [
WLEDEstimatedCurrentSensor(entry.entry_id, coordinator),
WLEDUptimeSensor(entry.entry_id, coordinator),
WLEDFreeHeapSensor(entry.entry_id, coordinator),
WLEDWifiBSSIDSensor(entry.entry_id, coordinator),
WLEDWifiChannelSensor(entry.entry_id, coordinator),
WLEDWifiRSSISensor(entry.entry_id, coordinator),
WLEDWifiSignalSensor(entry.entry_id, coordinator),
WLEDEstimatedCurrentSensor(coordinator),
WLEDUptimeSensor(coordinator),
WLEDFreeHeapSensor(coordinator),
WLEDWifiBSSIDSensor(coordinator),
WLEDWifiChannelSensor(coordinator),
WLEDWifiRSSISensor(coordinator),
WLEDWifiSignalSensor(coordinator),
]
async_add_entities(sensors, True)
class WLEDSensor(WLEDDeviceEntity, SensorEntity):
"""Defines a WLED sensor."""
def __init__(
self,
*,
coordinator: WLEDDataUpdateCoordinator,
enabled_default: bool = True,
entry_id: str,
icon: str,
key: str,
name: str,
unit_of_measurement: str | None = None,
) -> None:
"""Initialize WLED sensor."""
self._unit_of_measurement = unit_of_measurement
self._key = key
super().__init__(
entry_id=entry_id,
coordinator=coordinator,
name=name,
icon=icon,
enabled_default=enabled_default,
)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return f"{self.coordinator.data.info.mac_address}_{self._key}"
@property
def unit_of_measurement(self) -> str | None:
"""Return the unit this state is expressed in."""
return self._unit_of_measurement
class WLEDEstimatedCurrentSensor(WLEDSensor):
class WLEDEstimatedCurrentSensor(WLEDEntity, SensorEntity):
"""Defines a WLED estimated current sensor."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:power"
_attr_unit_of_measurement = CURRENT_MA
_attr_device_class = DEVICE_CLASS_CURRENT
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED estimated current sensor."""
super().__init__(
coordinator=coordinator,
entry_id=entry_id,
icon="mdi:power",
key="estimated_current",
name=f"{coordinator.data.info.name} Estimated Current",
unit_of_measurement=CURRENT_MA,
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Estimated Current"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_estimated_current"
@property
def extra_state_attributes(self) -> dict[str, Any] | None:
@ -106,25 +68,18 @@ class WLEDEstimatedCurrentSensor(WLEDSensor):
"""Return the state of the sensor."""
return self.coordinator.data.info.leds.power
@property
def device_class(self) -> str | None:
"""Return the class of this sensor."""
return DEVICE_CLASS_CURRENT
class WLEDUptimeSensor(WLEDSensor):
class WLEDUptimeSensor(WLEDEntity, SensorEntity):
"""Defines a WLED uptime sensor."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_device_class = DEVICE_CLASS_TIMESTAMP
_attr_entity_registry_enabled_default = False
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED uptime sensor."""
super().__init__(
coordinator=coordinator,
enabled_default=False,
entry_id=entry_id,
icon="mdi:clock-outline",
key="uptime",
name=f"{coordinator.data.info.name} Uptime",
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Uptime"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_uptime"
@property
def state(self) -> str:
@ -132,26 +87,19 @@ class WLEDUptimeSensor(WLEDSensor):
uptime = utcnow() - timedelta(seconds=self.coordinator.data.info.uptime)
return uptime.replace(microsecond=0).isoformat()
@property
def device_class(self) -> str | None:
"""Return the class of this sensor."""
return DEVICE_CLASS_TIMESTAMP
class WLEDFreeHeapSensor(WLEDSensor):
class WLEDFreeHeapSensor(WLEDEntity, SensorEntity):
"""Defines a WLED free heap sensor."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:memory"
_attr_entity_registry_enabled_default = False
_attr_unit_of_measurement = DATA_BYTES
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED free heap sensor."""
super().__init__(
coordinator=coordinator,
enabled_default=False,
entry_id=entry_id,
icon="mdi:memory",
key="free_heap",
name=f"{coordinator.data.info.name} Free Memory",
unit_of_measurement=DATA_BYTES,
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Free Memory"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_free_heap"
@property
def state(self) -> int:
@ -159,20 +107,18 @@ class WLEDFreeHeapSensor(WLEDSensor):
return self.coordinator.data.info.free_heap
class WLEDWifiSignalSensor(WLEDSensor):
class WLEDWifiSignalSensor(WLEDEntity, SensorEntity):
"""Defines a WLED Wi-Fi signal sensor."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:wifi"
_attr_unit_of_measurement = PERCENTAGE
_attr_entity_registry_enabled_default = False
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED Wi-Fi signal sensor."""
super().__init__(
coordinator=coordinator,
enabled_default=False,
entry_id=entry_id,
icon="mdi:wifi",
key="wifi_signal",
name=f"{coordinator.data.info.name} Wi-Fi Signal",
unit_of_measurement=PERCENTAGE,
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Wi-Fi Signal"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_wifi_signal"
@property
def state(self) -> int:
@ -180,45 +126,36 @@ class WLEDWifiSignalSensor(WLEDSensor):
return self.coordinator.data.info.wifi.signal
class WLEDWifiRSSISensor(WLEDSensor):
class WLEDWifiRSSISensor(WLEDEntity, SensorEntity):
"""Defines a WLED Wi-Fi RSSI sensor."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_device_class = DEVICE_CLASS_SIGNAL_STRENGTH
_attr_unit_of_measurement = SIGNAL_STRENGTH_DECIBELS_MILLIWATT
_attr_entity_registry_enabled_default = False
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED Wi-Fi RSSI sensor."""
super().__init__(
coordinator=coordinator,
enabled_default=False,
entry_id=entry_id,
icon="mdi:wifi",
key="wifi_rssi",
name=f"{coordinator.data.info.name} Wi-Fi RSSI",
unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Wi-Fi RSSI"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_wifi_rssi"
@property
def state(self) -> int:
"""Return the state of the sensor."""
return self.coordinator.data.info.wifi.rssi
@property
def device_class(self) -> str | None:
"""Return the class of this sensor."""
return DEVICE_CLASS_SIGNAL_STRENGTH
class WLEDWifiChannelSensor(WLEDSensor):
class WLEDWifiChannelSensor(WLEDEntity, SensorEntity):
"""Defines a WLED Wi-Fi Channel sensor."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:wifi"
_attr_entity_registry_enabled_default = False
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED Wi-Fi Channel sensor."""
super().__init__(
coordinator=coordinator,
enabled_default=False,
entry_id=entry_id,
icon="mdi:wifi",
key="wifi_channel",
name=f"{coordinator.data.info.name} Wi-Fi Channel",
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Wi-Fi Channel"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_wifi_channel"
@property
def state(self) -> int:
@ -226,19 +163,17 @@ class WLEDWifiChannelSensor(WLEDSensor):
return self.coordinator.data.info.wifi.channel
class WLEDWifiBSSIDSensor(WLEDSensor):
class WLEDWifiBSSIDSensor(WLEDEntity, SensorEntity):
"""Defines a WLED Wi-Fi BSSID sensor."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:wifi"
_attr_entity_registry_enabled_default = False
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED Wi-Fi BSSID sensor."""
super().__init__(
coordinator=coordinator,
enabled_default=False,
entry_id=entry_id,
icon="mdi:wifi",
key="wifi_bssid",
name=f"{coordinator.data.info.name} Wi-Fi BSSID",
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Wi-Fi BSSID"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_wifi_bssid"
@property
def state(self) -> str:

View file

@ -8,7 +8,7 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import WLEDDataUpdateCoordinator, WLEDDeviceEntity, wled_exception_handler
from . import WLEDDataUpdateCoordinator, WLEDEntity, wled_exception_handler
from .const import (
ATTR_DURATION,
ATTR_FADE,
@ -29,49 +29,23 @@ async def async_setup_entry(
coordinator: WLEDDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
switches = [
WLEDNightlightSwitch(entry.entry_id, coordinator),
WLEDSyncSendSwitch(entry.entry_id, coordinator),
WLEDSyncReceiveSwitch(entry.entry_id, coordinator),
WLEDNightlightSwitch(coordinator),
WLEDSyncSendSwitch(coordinator),
WLEDSyncReceiveSwitch(coordinator),
]
async_add_entities(switches, True)
class WLEDSwitch(WLEDDeviceEntity, SwitchEntity):
"""Defines a WLED switch."""
def __init__(
self,
*,
entry_id: str,
coordinator: WLEDDataUpdateCoordinator,
name: str,
icon: str,
key: str,
) -> None:
"""Initialize WLED switch."""
self._key = key
super().__init__(
entry_id=entry_id, coordinator=coordinator, name=name, icon=icon
)
@property
def unique_id(self) -> str:
"""Return the unique ID for this sensor."""
return f"{self.coordinator.data.info.mac_address}_{self._key}"
class WLEDNightlightSwitch(WLEDSwitch):
class WLEDNightlightSwitch(WLEDEntity, SwitchEntity):
"""Defines a WLED nightlight switch."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:weather-night"
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED nightlight switch."""
super().__init__(
coordinator=coordinator,
entry_id=entry_id,
icon="mdi:weather-night",
key="nightlight",
name=f"{coordinator.data.info.name} Nightlight",
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Nightlight"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_nightlight"
@property
def extra_state_attributes(self) -> dict[str, Any] | None:
@ -98,18 +72,16 @@ class WLEDNightlightSwitch(WLEDSwitch):
await self.coordinator.wled.nightlight(on=True)
class WLEDSyncSendSwitch(WLEDSwitch):
class WLEDSyncSendSwitch(WLEDEntity, SwitchEntity):
"""Defines a WLED sync send switch."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:upload-network-outline"
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED sync send switch."""
super().__init__(
coordinator=coordinator,
entry_id=entry_id,
icon="mdi:upload-network-outline",
key="sync_send",
name=f"{coordinator.data.info.name} Sync Send",
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Sync Send"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_sync_send"
@property
def extra_state_attributes(self) -> dict[str, Any] | None:
@ -132,18 +104,16 @@ class WLEDSyncSendSwitch(WLEDSwitch):
await self.coordinator.wled.sync(send=True)
class WLEDSyncReceiveSwitch(WLEDSwitch):
class WLEDSyncReceiveSwitch(WLEDEntity, SwitchEntity):
"""Defines a WLED sync receive switch."""
def __init__(self, entry_id: str, coordinator: WLEDDataUpdateCoordinator) -> None:
_attr_icon = "mdi:download-network-outline"
def __init__(self, coordinator: WLEDDataUpdateCoordinator) -> None:
"""Initialize WLED sync receive switch."""
super().__init__(
coordinator=coordinator,
entry_id=entry_id,
icon="mdi:download-network-outline",
key="sync_receive",
name=f"{coordinator.data.info.name} Sync Receive",
)
super().__init__(coordinator=coordinator)
self._attr_name = f"{coordinator.data.info.name} Sync Receive"
self._attr_unique_id = f"{coordinator.data.info.mac_address}_sync_receive"
@property
def extra_state_attributes(self) -> dict[str, Any] | None:

View file

@ -6,6 +6,8 @@ import pytest
from homeassistant.components.sensor import (
DEVICE_CLASS_CURRENT,
DEVICE_CLASS_SIGNAL_STRENGTH,
DEVICE_CLASS_TIMESTAMP,
DOMAIN as SENSOR_DOMAIN,
)
from homeassistant.components.wled.const import (
@ -108,7 +110,7 @@ async def test_sensors(
state = hass.states.get("sensor.wled_rgb_light_uptime")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:clock-outline"
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_TIMESTAMP
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) is None
assert state.state == "2019-11-11T09:10:00+00:00"
@ -138,7 +140,7 @@ async def test_sensors(
state = hass.states.get("sensor.wled_rgb_light_wifi_rssi")
assert state
assert state.attributes.get(ATTR_ICON) == "mdi:wifi"
assert state.attributes.get(ATTR_DEVICE_CLASS) == DEVICE_CLASS_SIGNAL_STRENGTH
assert (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT)
== SIGNAL_STRENGTH_DECIBELS_MILLIWATT