Skip to content

Commit

Permalink
Merge branch 'dev' into mqtt-device-based-discovery
Browse files Browse the repository at this point in the history
  • Loading branch information
jbouwh authored Jul 30, 2024
2 parents 2f76102 + 70e368a commit 3959c27
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 98 deletions.
53 changes: 35 additions & 18 deletions homeassistant/components/bluesound/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import config_validation as cv, issue_registry as ir
from homeassistant.helpers.device_registry import (
CONNECTION_NETWORK_MAC,
DeviceInfo,
format_mac,
)
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
Expand Down Expand Up @@ -280,6 +285,8 @@ class BluesoundPlayer(MediaPlayerEntity):
"""Representation of a Bluesound Player."""

_attr_media_content_type = MediaType.MUSIC
_attr_has_entity_name = True
_attr_name = None

def __init__(
self,
Expand All @@ -295,7 +302,6 @@ def __init__(
self._hass = hass
self.port = port
self._polling_task = None # The actual polling task.
self._name = sync_status.name
self._id = None
self._last_status_update = None
self._sync_status: SyncStatus | None = None
Expand All @@ -314,6 +320,27 @@ def __init__(

self._init_callback = init_callback

self._attr_unique_id = format_unique_id(sync_status.mac, port)
# there should always be one player with the default port per mac
if port is DEFAULT_PORT:
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, format_mac(sync_status.mac))},
connections={(CONNECTION_NETWORK_MAC, format_mac(sync_status.mac))},
name=sync_status.name,
manufacturer=sync_status.brand,
model=sync_status.model_name,
model_id=sync_status.model,
)
else:
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, format_unique_id(sync_status.mac, port))},
name=sync_status.name,
manufacturer=sync_status.brand,
model=sync_status.model_name,
model_id=sync_status.model,
via_device=(DOMAIN, format_mac(sync_status.mac)),
)

@staticmethod
def _try_get_index(string, search_string):
"""Get the index."""
Expand All @@ -328,12 +355,10 @@ async def force_update_sync_status(self, on_updated_cb=None) -> bool:

self._sync_status = sync_status

if not self._name:
self._name = sync_status.name if sync_status.name else self.host
if not self._id:
self._id = sync_status.id
if not self._bluesound_device_name:
self._bluesound_device_name = self._name
self._bluesound_device_name = sync_status.name

if sync_status.master is not None:
self._is_master = False
Expand Down Expand Up @@ -366,7 +391,7 @@ async def _start_poll_command(self):
await self.async_update_status()

except (TimeoutError, ClientError):
_LOGGER.info("Node %s:%s is offline, retrying later", self.name, self.port)
_LOGGER.error("Node %s:%s is offline, retrying later", self.name, self.port)
await asyncio.sleep(NODE_OFFLINE_CHECK_TIMEOUT)
self.start_polling()

Expand All @@ -393,7 +418,7 @@ async def async_init(self, triggered=None):

await self.force_update_sync_status(self._init_callback)
except (TimeoutError, ClientError):
_LOGGER.info("Node %s:%s is offline, retrying later", self.host, self.port)
_LOGGER.error("Node %s:%s is offline, retrying later", self.host, self.port)
self._retry_remove = async_track_time_interval(
self._hass, self.async_init, NODE_RETRY_INITIATION
)
Expand Down Expand Up @@ -455,15 +480,12 @@ async def async_update_status(self):
self._last_status_update = None
self._status = None
self.async_write_ha_state()
_LOGGER.info("Client connection error, marking %s as offline", self._name)
_LOGGER.error(
"Client connection error, marking %s as offline",
self._bluesound_device_name,
)
raise

@property
def unique_id(self) -> str:
"""Return an unique ID."""
assert self._sync_status is not None
return format_unique_id(self._sync_status.mac, self.port)

async def async_trigger_sync_on_all(self):
"""Trigger sync status update on all devices."""
_LOGGER.debug("Trigger sync status on all devices")
Expand Down Expand Up @@ -618,11 +640,6 @@ def id(self) -> str | None:
"""Get id of device."""
return self._id

@property
def name(self) -> str | None:
"""Return the name of the device."""
return self._name

@property
def bluesound_device_name(self) -> str | None:
"""Return the device name as returned by the device."""
Expand Down
29 changes: 24 additions & 5 deletions homeassistant/components/zha/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import functools
from typing import Any

from zha.application.platforms.fan.const import FanEntityFeature as ZHAFanEntityFeature

from homeassistant.components.fan import FanEntity, FanEntityFeature
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
Expand All @@ -15,6 +17,7 @@
from .entity import ZHAEntity
from .helpers import (
SIGNAL_ADD_ENTITIES,
EntityData,
async_add_entities as zha_async_add_entities,
convert_zha_error_to_ha_error,
get_zha_data,
Expand Down Expand Up @@ -43,14 +46,30 @@ async def async_setup_entry(
class ZhaFan(FanEntity, ZHAEntity):
"""Representation of a ZHA fan."""

_attr_supported_features = (
FanEntityFeature.SET_SPEED
| FanEntityFeature.TURN_OFF
| FanEntityFeature.TURN_ON
)
_attr_translation_key: str = "fan"
_enable_turn_on_off_backwards_compatibility = False

def __init__(self, entity_data: EntityData) -> None:
"""Initialize the ZHA fan."""
super().__init__(entity_data)
features = FanEntityFeature(0)
zha_features: ZHAFanEntityFeature = self.entity_data.entity.supported_features

if ZHAFanEntityFeature.DIRECTION in zha_features:
features |= FanEntityFeature.DIRECTION
if ZHAFanEntityFeature.OSCILLATE in zha_features:
features |= FanEntityFeature.OSCILLATE
if ZHAFanEntityFeature.PRESET_MODE in zha_features:
features |= FanEntityFeature.PRESET_MODE
if ZHAFanEntityFeature.SET_SPEED in zha_features:
features |= FanEntityFeature.SET_SPEED
if ZHAFanEntityFeature.TURN_ON in zha_features:
features |= FanEntityFeature.TURN_ON
if ZHAFanEntityFeature.TURN_OFF in zha_features:
features |= FanEntityFeature.TURN_OFF

self._attr_supported_features = features

@property
def preset_mode(self) -> str | None:
"""Return the current preset mode."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/zha/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"zha",
"universal_silabs_flasher"
],
"requirements": ["universal-silabs-flasher==0.0.21", "zha==0.0.23"],
"requirements": ["universal-silabs-flasher==0.0.22", "zha==0.0.24"],
"usb": [
{
"vid": "10C4",
Expand Down
6 changes: 1 addition & 5 deletions homeassistant/components/zha/websocket_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -1311,12 +1311,8 @@ async def remove(service: ServiceCall) -> None:
"""Remove a node from the network."""
zha_gateway = get_zha_gateway(hass)
ieee: EUI64 = service.data[ATTR_IEEE]
zha_device: Device | None = zha_gateway.get_device(ieee)
if zha_device is not None and zha_device.is_active_coordinator:
_LOGGER.info("Removing the coordinator (%s) is not allowed", ieee)
return
_LOGGER.info("Removing node %s", ieee)
await application_controller.remove(ieee)
await zha_gateway.async_remove_device(ieee)
async_register_admin_service(
hass, DOMAIN, SERVICE_REMOVE, remove, schema=SERVICE_SCHEMAS[IEEE_SERVICE]
Expand Down
4 changes: 2 additions & 2 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2822,7 +2822,7 @@ unifi_ap==0.0.1
unifiled==0.11

# homeassistant.components.zha
universal-silabs-flasher==0.0.21
universal-silabs-flasher==0.0.22

# homeassistant.components.upb
upb-lib==0.5.8
Expand Down Expand Up @@ -2983,7 +2983,7 @@ zeroconf==0.132.2
zeversolar==0.3.1

# homeassistant.components.zha
zha==0.0.23
zha==0.0.24

# homeassistant.components.zhong_hong
zhong-hong-hvac==1.0.12
Expand Down
4 changes: 2 additions & 2 deletions requirements_test_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2217,7 +2217,7 @@ ultraheat-api==0.5.7
unifi-discovery==1.2.0

# homeassistant.components.zha
universal-silabs-flasher==0.0.21
universal-silabs-flasher==0.0.22

# homeassistant.components.upb
upb-lib==0.5.8
Expand Down Expand Up @@ -2357,7 +2357,7 @@ zeroconf==0.132.2
zeversolar==0.3.1

# homeassistant.components.zha
zha==0.0.23
zha==0.0.24

# homeassistant.components.zwave_js
zwave-js-server-python==0.57.0
Expand Down
Loading

0 comments on commit 3959c27

Please sign in to comment.