Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Nearest scanner entity_id sensor #374

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
28 changes: 28 additions & 0 deletions custom_components/bermuda/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ def __init__(
self._entity_registry = er.async_get(self.hass)
self._device_registry = dr.async_get(self.hass)

# Add storage for scanner entity IDs
self.scanner_entity_ids: dict[str, str] = {}

# Track the list of Private BLE devices, noting their entity id
# and current "last address".
self.pb_state_sources: dict[str, str | None] = {}
Expand Down Expand Up @@ -1120,6 +1123,9 @@ def _refresh_scanners(self, scanners: list[BluetoothScannerDevice] | None = None
_previous_scannerlist = [device.address for device in self.devices.values() if device.is_scanner]
_purge_scanners = _previous_scannerlist.copy()

# Clear existing mappings to ensure fresh start
self.scanner_entity_ids.clear()

# _LOGGER.error("Preserving %d current scanner entries", len(_previous_scannerlist))

# Find active HaBaseScanners in the backend, and only pay attention to those
Expand Down Expand Up @@ -1147,6 +1153,28 @@ def _refresh_scanners(self, scanners: list[BluetoothScannerDevice] | None = None
hascanner.source,
)
continue

if scanner_devreg:
_LOGGER.debug("Found device entry id: %s", scanner_devreg.id)

# Get all entities for this device
entities = list(self._entity_registry.entities.get_entries_for_device_id(scanner_devreg.id))

if len(entities) > 1:
# Device must have multiple entities. Reduce search space
entities = [entity for entity in entities if entity.domain in ("switch", "light")]
if entities:
# Take the first valid entity
self.scanner_entity_ids[scanner_address] = entities[0].entity_id
_LOGGER.debug(
"Mapped scanner %s (%s) to entity %s",
scanner_devreg.name,
scanner_address,
entities[0].entity_id,
)
else:
_LOGGER.debug("No entity found for scanner %s", scanner_address)

# _LOGGER.info("Great! Found scanner: %s (%s)", scanner_ha.name, scanner_ha.source)
# Since this scanner still exists, we won't purge it
if scanner_address in _purge_scanners:
Expand Down
18 changes: 18 additions & 0 deletions custom_components/bermuda/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,24 @@ def name(self):
def native_value(self):
return self._device.area_scanner

@property
def extra_state_attributes(self) -> Mapping[str, Any] | None:
"""Return extra state attributes for the nearest scanner."""
attribs = super().extra_state_attributes or {}

if self._device.area_scanner:
for scanner in self.coordinator.scanner_list:
scanner_device = self.coordinator.devices[scanner]
if scanner_device.address.upper() in self._device.area_scanner:
if scanner_device.address in self.coordinator.scanner_entity_ids:
attribs["scanner_entity_id"] = self.coordinator.scanner_entity_ids[scanner_device.address]
_LOGGER.debug(
"Set scanner_entity_id to %s for device %s", attribs["scanner_entity_id"], self._device.name
)
break

return attribs


class BermudaSensorRssi(BermudaSensor):
"""Sensor for RSSI of closest scanner."""
Expand Down