125 lines
4.0 KiB
Python
125 lines
4.0 KiB
Python
from __future__ import annotations
|
|
|
|
from decimal import Decimal
|
|
import logging
|
|
from typing import cast
|
|
|
|
from homeassistant.const import CONF_ENTITY_ID, CONF_NAME, CONF_UNIQUE_ID, STATE_UNAVAILABLE
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity import Entity
|
|
from homeassistant.helpers.typing import ConfigType
|
|
|
|
from custom_components.powercalc.const import (
|
|
CONF_CREATE_ENERGY_SENSORS,
|
|
CONF_SUBTRACT_ENTITIES,
|
|
CONF_UTILITY_METER_NET_CONSUMPTION,
|
|
GroupType,
|
|
)
|
|
from custom_components.powercalc.errors import SensorConfigurationError
|
|
from custom_components.powercalc.sensors.abstract import generate_power_sensor_entity_id, generate_power_sensor_name
|
|
from custom_components.powercalc.sensors.energy import create_energy_sensor
|
|
from custom_components.powercalc.sensors.energy_related import create_energy_related_sensors
|
|
from custom_components.powercalc.sensors.group.custom import GroupedPowerSensor
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
def create_subtract_group_sensors(
|
|
hass: HomeAssistant,
|
|
config: ConfigType,
|
|
) -> list[Entity]:
|
|
"""Create subtract group sensors."""
|
|
|
|
validate_config(config)
|
|
group_name = str(config.get(CONF_NAME))
|
|
base_entity_id = str(config.get(CONF_ENTITY_ID))
|
|
subtract_entities = cast(list[str], config.get(CONF_SUBTRACT_ENTITIES))
|
|
|
|
name = generate_power_sensor_name(config, group_name)
|
|
unique_id = config.get(CONF_UNIQUE_ID, generate_unique_id(config))
|
|
entity_id = generate_power_sensor_entity_id(
|
|
hass,
|
|
config,
|
|
name=group_name,
|
|
unique_id=unique_id,
|
|
)
|
|
|
|
_LOGGER.debug("Creating grouped power sensor: %s (entity_id=%s)", name, entity_id)
|
|
|
|
sensors: list[Entity] = []
|
|
power_sensor = SubtractGroupSensor(
|
|
hass,
|
|
name,
|
|
config,
|
|
entity_id,
|
|
base_entity_id,
|
|
subtract_entities,
|
|
unique_id=unique_id,
|
|
)
|
|
sensors.append(power_sensor)
|
|
if config.get(CONF_CREATE_ENERGY_SENSORS):
|
|
energy_sensor = create_energy_sensor(
|
|
hass,
|
|
config,
|
|
power_sensor,
|
|
)
|
|
sensors.append(energy_sensor)
|
|
|
|
config[CONF_UTILITY_METER_NET_CONSUMPTION] = True
|
|
sensors.extend(create_energy_related_sensors(hass, config, energy_sensor))
|
|
return sensors
|
|
|
|
|
|
def generate_unique_id(sensor_config: ConfigType) -> str:
|
|
"""Generate unique_id for subtract group sensor."""
|
|
base_entity_id = str(sensor_config[CONF_ENTITY_ID])
|
|
return f"pc_subtract_{base_entity_id}"
|
|
|
|
|
|
def validate_config(config: ConfigType) -> None:
|
|
"""Validate subtract group sensor configuration."""
|
|
if CONF_NAME not in config:
|
|
raise SensorConfigurationError("name is required")
|
|
|
|
if CONF_ENTITY_ID not in config:
|
|
raise SensorConfigurationError("entity_id is required")
|
|
|
|
if CONF_SUBTRACT_ENTITIES not in config:
|
|
raise SensorConfigurationError("subtract_entities is required")
|
|
|
|
|
|
class SubtractGroupSensor(GroupedPowerSensor):
|
|
def __init__(
|
|
self,
|
|
hass: HomeAssistant,
|
|
name: str,
|
|
sensor_config: ConfigType,
|
|
entity_id: str,
|
|
base_entity_id: str,
|
|
subtract_entities: list[str],
|
|
unique_id: str | None = None,
|
|
) -> None:
|
|
all_entities = {base_entity_id, *subtract_entities}
|
|
|
|
super().__init__(
|
|
hass=hass,
|
|
name=name,
|
|
entities=all_entities,
|
|
entity_id=entity_id,
|
|
sensor_config=sensor_config,
|
|
group_type=GroupType.SUBTRACT,
|
|
unique_id=unique_id,
|
|
)
|
|
|
|
self._base_entity_id = base_entity_id
|
|
self._subtract_entities = subtract_entities
|
|
|
|
def get_summed_state(self) -> Decimal | str:
|
|
base_value = self._member_states.get(self._base_entity_id)
|
|
if base_value is None:
|
|
return STATE_UNAVAILABLE
|
|
subtracted_value = base_value
|
|
for entity_id in self._subtract_entities:
|
|
subtracted_value -= self._member_states.get(entity_id, 0)
|
|
return subtracted_value
|