Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 1 addition & 53 deletions homeassistant/components/honeywell_string_lights/entity.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
"""Common entity for Honeywell String Lights integration."""

import logging

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import Event, EventStateChangedData, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_state_change_event

from .const import CONF_TRANSMITTER, DOMAIN

_LOGGER = logging.getLogger(__name__)
from .const import DOMAIN


class HoneywellStringLightsEntity(Entity):
Expand All @@ -22,53 +14,9 @@ class HoneywellStringLightsEntity(Entity):

def __init__(self, entry: ConfigEntry) -> None:
"""Initialize the entity."""
self._transmitter = entry.data[CONF_TRANSMITTER]
self._attr_unique_id = entry.entry_id
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, entry.entry_id)},
manufacturer="Honeywell",
model="String Lights",
)

async def async_added_to_hass(self) -> None:
"""Subscribe to transmitter entity state changes."""
await super().async_added_to_hass()

transmitter_entity_id = er.async_validate_entity_id(
er.async_get(self.hass), self._transmitter
)

@callback
def _async_transmitter_state_changed(
event: Event[EventStateChangedData],
) -> None:
"""Handle transmitter entity state changes."""
new_state = event.data["new_state"]
transmitter_available = (
new_state is not None and new_state.state != STATE_UNAVAILABLE
)
if transmitter_available != self.available:
_LOGGER.info(
"Transmitter %s used by %s is %s",
transmitter_entity_id,
self.entity_id,
"available" if transmitter_available else "unavailable",
)

self._attr_available = transmitter_available
self.async_write_ha_state()

self.async_on_remove(
async_track_state_change_event(
self.hass,
[transmitter_entity_id],
_async_transmitter_state_changed,
)
)

# Set initial availability based on current transmitter entity state
transmitter_state = self.hass.states.get(transmitter_entity_id)
self._attr_available = (
transmitter_state is not None
and transmitter_state.state != STATE_UNAVAILABLE
)
28 changes: 19 additions & 9 deletions homeassistant/components/honeywell_string_lights/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
from rf_protocols.codes.honeywell.string_lights import CODES

from homeassistant.components.light import ColorMode, LightEntity
from homeassistant.components.radio_frequency import async_send_command
from homeassistant.components.radio_frequency import (
RadioFrequencyTransmitterConsumerEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_ON
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity

from .const import CONF_TRANSMITTER
from .entity import HoneywellStringLightsEntity

PARALLEL_UPDATES = 1
Expand All @@ -26,14 +29,23 @@ async def async_setup_entry(
async_add_entities([HoneywellStringLight(config_entry)])


class HoneywellStringLight(HoneywellStringLightsEntity, LightEntity, RestoreEntity):
class HoneywellStringLight(
HoneywellStringLightsEntity,
RadioFrequencyTransmitterConsumerEntity,
LightEntity,
RestoreEntity,
):
"""Representation of a Honeywell String Lights set controlled via RF."""

_attr_assumed_state = True
_attr_color_mode = ColorMode.ONOFF
_attr_supported_color_modes = {ColorMode.ONOFF}
_attr_name = None
_attr_should_poll = False

def __init__(self, entry: ConfigEntry) -> None:
"""Initialize the entity."""
super().__init__(entry)
self._rf_transmitter_entity_id = entry.data[CONF_TRANSMITTER]
Comment thread
balloob marked this conversation as resolved.

async def async_added_to_hass(self) -> None:
"""Restore last known state."""
Expand All @@ -43,19 +55,17 @@ async def async_added_to_hass(self) -> None:

async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the light."""
await self._async_send_command("turn_on")
await self._async_send_rf_command("turn_on")
self._attr_is_on = True
self.async_write_ha_state()

async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the light."""
await self._async_send_command("turn_off")
await self._async_send_rf_command("turn_off")
self._attr_is_on = False
self.async_write_ha_state()

async def _async_send_command(self, name: str) -> None:
async def _async_send_rf_command(self, name: str) -> None:
"""Load the named command and send it via the configured transmitter."""
command = await CODES.async_load_command(name)
await async_send_command(
self.hass, self._transmitter, command, context=self._context
)
await self._send_command(command)
54 changes: 1 addition & 53 deletions homeassistant/components/novy_cooker_hood/entity.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,22 @@
"""Common entity for the Novy Cooker Hood integration."""

import logging

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import Event, EventStateChangedData, callback
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_state_change_event

from .const import CONF_TRANSMITTER, DOMAIN

_LOGGER = logging.getLogger(__name__)
from .const import DOMAIN


class NovyCookerHoodEntity(Entity):
"""Novy Cooker Hood base entity."""

_attr_assumed_state = True
_attr_has_entity_name = True
_attr_should_poll = False

def __init__(self, entry: ConfigEntry) -> None:
"""Initialize the entity."""
self._transmitter = entry.data[CONF_TRANSMITTER]
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, entry.entry_id)},
manufacturer="Novy",
model="Cooker Hood",
)

async def async_added_to_hass(self) -> None:
"""Subscribe to transmitter entity state changes."""
await super().async_added_to_hass()

transmitter_entity_id = er.async_validate_entity_id(
er.async_get(self.hass), self._transmitter
)

@callback
def _async_transmitter_state_changed(
event: Event[EventStateChangedData],
) -> None:
"""Handle transmitter entity state changes."""
new_state = event.data["new_state"]
transmitter_available = (
new_state is not None and new_state.state != STATE_UNAVAILABLE
)
if transmitter_available != self.available:
_LOGGER.info(
"Transmitter %s used by %s is %s",
transmitter_entity_id,
self.entity_id,
"available" if transmitter_available else "unavailable",
)

self._attr_available = transmitter_available
self.async_write_ha_state()

self.async_on_remove(
async_track_state_change_event(
self.hass,
[transmitter_entity_id],
_async_transmitter_state_changed,
)
)

transmitter_state = self.hass.states.get(transmitter_entity_id)
self._attr_available = (
transmitter_state is not None
and transmitter_state.state != STATE_UNAVAILABLE
)
28 changes: 15 additions & 13 deletions homeassistant/components/novy_cooker_hood/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
from rf_protocols.codes.novy.cooker_hood import get_codes_for_code

from homeassistant.components.fan import ATTR_PERCENTAGE, FanEntity, FanEntityFeature
from homeassistant.components.radio_frequency import async_send_command
from homeassistant.components.radio_frequency import (
RadioFrequencyTransmitterConsumerEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
Expand All @@ -17,7 +19,7 @@
)

from .commands import COMMAND_MINUS, COMMAND_PLUS
from .const import CONF_CODE, SPEED_COUNT
from .const import CONF_CODE, CONF_TRANSMITTER, SPEED_COUNT
from .entity import NovyCookerHoodEntity

PARALLEL_UPDATES = 1
Expand All @@ -34,7 +36,12 @@ async def async_setup_entry(
async_add_entities([NovyCookerHoodFan(config_entry)])


class NovyCookerHoodFan(NovyCookerHoodEntity, FanEntity, RestoreEntity):
class NovyCookerHoodFan(
NovyCookerHoodEntity,
RadioFrequencyTransmitterConsumerEntity,
FanEntity,
RestoreEntity,
):
"""Calibration-based fan: each change resets to off then climbs to target."""

_attr_name = None
Expand All @@ -48,6 +55,7 @@ class NovyCookerHoodFan(NovyCookerHoodEntity, FanEntity, RestoreEntity):
def __init__(self, entry: ConfigEntry) -> None:
"""Initialize the fan."""
super().__init__(entry)
self._rf_transmitter_entity_id = entry.data[CONF_TRANSMITTER]
Comment thread
balloob marked this conversation as resolved.
self._codes = get_codes_for_code(entry.data[CONF_CODE])
self._level = 0
self._attr_unique_id = entry.entry_id
Expand Down Expand Up @@ -104,7 +112,7 @@ async def async_increase_speed(self, percentage_step: int | None = None) -> None
steps = self._steps_from_percentage(percentage_step)
plus = await self._codes.async_load_command(COMMAND_PLUS)
for _ in range(steps):
await self._async_send(plus)
await self._send_command(plus)
self._level = min(SPEED_COUNT, self._level + steps)
self.async_write_ha_state()

Expand All @@ -113,7 +121,7 @@ async def async_decrease_speed(self, percentage_step: int | None = None) -> None
steps = self._steps_from_percentage(percentage_step)
minus = await self._codes.async_load_command(COMMAND_MINUS)
for _ in range(steps):
await self._async_send(minus)
await self._send_command(minus)
self._level = max(0, self._level - steps)
self.async_write_ha_state()

Expand All @@ -128,16 +136,10 @@ async def _async_set_level(self, level: int) -> None:
"""Reset to off with `SPEED_COUNT` minus presses, then climb to level."""
minus = await self._codes.async_load_command(COMMAND_MINUS)
for _ in range(SPEED_COUNT):
await self._async_send(minus)
await self._send_command(minus)
if level > 0:
plus = await self._codes.async_load_command(COMMAND_PLUS)
for _ in range(level):
await self._async_send(plus)
await self._send_command(plus)
self._level = level
self.async_write_ha_state()

async def _async_send(self, command: Any) -> None:
"""Send a single RF command via the configured transmitter."""
await async_send_command(
self.hass, self._transmitter, command, context=self._context
)
24 changes: 15 additions & 9 deletions homeassistant/components/novy_cooker_hood/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
from rf_protocols.codes.novy.cooker_hood import get_codes_for_code

from homeassistant.components.light import ColorMode, LightEntity
from homeassistant.components.radio_frequency import async_send_command
from homeassistant.components.radio_frequency import (
RadioFrequencyTransmitterConsumerEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_ON
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity

from .commands import COMMAND_LIGHT
from .const import CONF_CODE
from .const import CONF_CODE, CONF_TRANSMITTER
from .entity import NovyCookerHoodEntity

PARALLEL_UPDATES = 1
Expand All @@ -28,7 +30,12 @@ async def async_setup_entry(
async_add_entities([NovyCookerHoodLight(config_entry)])


class NovyCookerHoodLight(NovyCookerHoodEntity, LightEntity, RestoreEntity):
class NovyCookerHoodLight(
NovyCookerHoodEntity,
RadioFrequencyTransmitterConsumerEntity,
LightEntity,
RestoreEntity,
):
"""Novy cooker hood light toggled via a single RF press."""

_attr_color_mode = ColorMode.ONOFF
Expand All @@ -38,6 +45,7 @@ class NovyCookerHoodLight(NovyCookerHoodEntity, LightEntity, RestoreEntity):
def __init__(self, entry: ConfigEntry) -> None:
"""Initialize the light."""
super().__init__(entry)
self._rf_transmitter_entity_id = entry.data[CONF_TRANSMITTER]
Comment thread
balloob marked this conversation as resolved.
self._codes = get_codes_for_code(entry.data[CONF_CODE])
self._attr_unique_id = entry.entry_id

Expand All @@ -49,19 +57,17 @@ async def async_added_to_hass(self) -> None:

async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the light on by sending the toggle command."""
await self._async_send_command(COMMAND_LIGHT)
await self._async_send_rf_command(COMMAND_LIGHT)
self._attr_is_on = True
self.async_write_ha_state()

async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the light off by sending the toggle command."""
await self._async_send_command(COMMAND_LIGHT)
await self._async_send_rf_command(COMMAND_LIGHT)
self._attr_is_on = False
self.async_write_ha_state()

async def _async_send_command(self, name: str) -> None:
async def _async_send_rf_command(self, name: str) -> None:
"""Load the named command and send it via the configured transmitter."""
command = await self._codes.async_load_command(name)
await async_send_command(
self.hass, self._transmitter, command, context=self._context
)
await self._send_command(command)
Loading