Skip to content

Commit

Permalink
Add sub profile matcher for entity_id
Browse files Browse the repository at this point in the history
  • Loading branch information
bramstroker committed Apr 1, 2023
1 parent b079397 commit 36f5453
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 5 deletions.
18 changes: 18 additions & 0 deletions custom_components/powercalc/power_profile/power_profile.py
Expand Up @@ -294,6 +294,8 @@ def _create_matcher(self, matcher_config: dict) -> SubProfileMatcher:
matcher_config["entity_id"],
matcher_config["map"],
)
if matcher_type == "entity_id":
return EntityIdMatcher(matcher_config["pattern"], matcher_config["profile"])
raise PowercalcSetupError(f"Unknown sub profile matcher type: {matcher_type}")


Expand Down Expand Up @@ -353,3 +355,19 @@ def match(self, entity_state: State) -> str | None:

def get_tracking_entities(self) -> list[str]:
return []


class EntityIdMatcher(SubProfileMatcher):
def __init__(self, pattern: str, profile: str):
self._pattern = pattern
self._profile = profile

def match(self, entity_state: State) -> str | None:
if re.search(self._pattern, entity_state.entity_id):
return self._profile

return None

def get_tracking_entities(self) -> list[str]:
return []

Check failure on line 373 in custom_components/powercalc/power_profile/power_profile.py

View workflow job for this annotation

GitHub Actions / flake8

custom_components/powercalc/power_profile/power_profile.py#L373

[W391] blank line at end of file
5 changes: 3 additions & 2 deletions custom_components/powercalc/sensor.py
Expand Up @@ -16,6 +16,7 @@
from homeassistant.components.utility_meter import max_28_days
from homeassistant.components.utility_meter.const import METER_TYPES
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.helpers.entity import DeviceInfo

Check failure on line 19 in custom_components/powercalc/sensor.py

View workflow job for this annotation

GitHub Actions / flake8

custom_components/powercalc/sensor.py#L19

[F401]
from homeassistant.const import (
CONF_DOMAIN,
CONF_ENTITIES,
Expand Down Expand Up @@ -564,10 +565,10 @@ async def create_individual_sensors( # noqa: C901
# Set the entity to same device as the source entity, if any available
if source_entity.entity_entry and source_entity.device_entry:
for entity in entities_to_add:
if not isinstance(entity, SensorEntity):
if not isinstance(entity, BaseEntity):
continue
try:
setattr(entity, "device_id", source_entity.device_entry.id)
setattr(entity, "source_device_id", source_entity.device_entry.id)
except AttributeError:
_LOGGER.error(f"{entity.entity_id}: Cannot set device id on entity")

Expand Down
8 changes: 5 additions & 3 deletions custom_components/powercalc/sensors/abstract.py
@@ -1,6 +1,7 @@
from __future__ import annotations

import logging
import traceback

Check failure on line 4 in custom_components/powercalc/sensors/abstract.py

View workflow job for this annotation

GitHub Actions / flake8

custom_components/powercalc/sensors/abstract.py#L4

[F401]
from typing import Any

import homeassistant.helpers.device_registry as dr
Expand All @@ -27,13 +28,12 @@
class BaseEntity(Entity):
async def async_added_to_hass(self) -> None:
"""Attach the entity to same device as the source entity"""

entity_reg = er.async_get(self.hass)
entity_entry = entity_reg.async_get(self.entity_id)
if entity_entry is None or not hasattr(self, "device_id"):
if entity_entry is None or not hasattr(self, "source_device_id"):
return

device_id: str = self.device_id
device_id: str = getattr(self, "source_device_id")
if not device_id:
return
device_reg = dr.async_get(self.hass)
Expand All @@ -43,6 +43,8 @@ async def async_added_to_hass(self) -> None:
_LOGGER.debug(f"Binding {self.entity_id} to device {device_id}")
entity_reg.async_update_entity(self.entity_id, device_id=device_id)

self.async_on_remove(lambda: _LOGGER.debug(f"Removing entity {self.entity_id}"))


def generate_power_sensor_name(
sensor_config: dict[str, Any],
Expand Down
15 changes: 15 additions & 0 deletions tests/power_profile/test_power_profile.py
Expand Up @@ -120,6 +120,21 @@ async def test_sub_profile_attribute_match(hass: HomeAssistant):
assert selector.select_sub_profile(state) == "b"


async def test_sub_profile_entity_id_match(hass: HomeAssistant):
power_profile = await ProfileLibrary.factory(hass).get_profile(
ModelInfo("Test", "Test"),
get_test_profile_dir("sub_profile_entity_id_match"),
)
selector = SubProfileSelector(hass, power_profile)
assert len(selector.get_tracking_entities()) == 0

state = State("light.test_nightlight", STATE_ON)
assert selector.select_sub_profile(state) == "nightlight"

state = State("light.test", STATE_ON)
assert selector.select_sub_profile(state) == "default"


async def test_exception_is_raised_when_invalid_sub_profile_matcher_supplied(
hass: HomeAssistant,
):
Expand Down
@@ -0,0 +1,15 @@
{
"name": "Test",
"standby_power": 0.47,
"calculation_strategy": "lut",
"sub_profile_select": {
"matchers": [
{
"type": "entity_id",
"pattern": ".*_nightlight$",
"profile": "nightlight"
}
],
"default": "default"
}
}

0 comments on commit 36f5453

Please sign in to comment.