diff --git a/homeassistant/components/energy/validate.py b/homeassistant/components/energy/validate.py index 62ff7beac5e..8fe188985fe 100644 --- a/homeassistant/components/energy/validate.py +++ b/homeassistant/components/energy/validate.py @@ -386,11 +386,260 @@ def _async_validate_auto_generated_cost_entity( issues.add_issue(hass, "recorder_untracked", cost_entity_id) +def _validate_grid_source( + hass: HomeAssistant, + source: data.GridSourceType, + statistics_metadata: dict[str, tuple[int, recorder.models.StatisticMetaData]], + wanted_statistics_metadata: set[str], + source_result: ValidationIssues, + validate_calls: list[functools.partial[None]], +) -> None: + """Validate grid energy source.""" + flow_from: data.FlowFromGridSourceType + for flow_from in source["flow_from"]: + wanted_statistics_metadata.add(flow_from["stat_energy_from"]) + validate_calls.append( + functools.partial( + _async_validate_usage_stat, + hass, + statistics_metadata, + flow_from["stat_energy_from"], + ENERGY_USAGE_DEVICE_CLASSES, + ENERGY_USAGE_UNITS, + ENERGY_UNIT_ERROR, + source_result, + ) + ) + + if (stat_cost := flow_from.get("stat_cost")) is not None: + wanted_statistics_metadata.add(stat_cost) + validate_calls.append( + functools.partial( + _async_validate_cost_stat, + hass, + statistics_metadata, + stat_cost, + source_result, + ) + ) + elif (entity_energy_price := flow_from.get("entity_energy_price")) is not None: + validate_calls.append( + functools.partial( + _async_validate_price_entity, + hass, + entity_energy_price, + source_result, + ENERGY_PRICE_UNITS, + ENERGY_PRICE_UNIT_ERROR, + ) + ) + + if ( + flow_from.get("entity_energy_price") is not None + or flow_from.get("number_energy_price") is not None + ): + validate_calls.append( + functools.partial( + _async_validate_auto_generated_cost_entity, + hass, + flow_from["stat_energy_from"], + source_result, + ) + ) + + flow_to: data.FlowToGridSourceType + for flow_to in source["flow_to"]: + wanted_statistics_metadata.add(flow_to["stat_energy_to"]) + validate_calls.append( + functools.partial( + _async_validate_usage_stat, + hass, + statistics_metadata, + flow_to["stat_energy_to"], + ENERGY_USAGE_DEVICE_CLASSES, + ENERGY_USAGE_UNITS, + ENERGY_UNIT_ERROR, + source_result, + ) + ) + + if (stat_compensation := flow_to.get("stat_compensation")) is not None: + wanted_statistics_metadata.add(stat_compensation) + validate_calls.append( + functools.partial( + _async_validate_cost_stat, + hass, + statistics_metadata, + stat_compensation, + source_result, + ) + ) + elif (entity_energy_price := flow_to.get("entity_energy_price")) is not None: + validate_calls.append( + functools.partial( + _async_validate_price_entity, + hass, + entity_energy_price, + source_result, + ENERGY_PRICE_UNITS, + ENERGY_PRICE_UNIT_ERROR, + ) + ) + + if ( + flow_to.get("entity_energy_price") is not None + or flow_to.get("number_energy_price") is not None + ): + validate_calls.append( + functools.partial( + _async_validate_auto_generated_cost_entity, + hass, + flow_to["stat_energy_to"], + source_result, + ) + ) + + for power_stat in source.get("power", []): + wanted_statistics_metadata.add(power_stat["stat_rate"]) + validate_calls.append( + functools.partial( + _async_validate_power_stat, + hass, + statistics_metadata, + power_stat["stat_rate"], + POWER_USAGE_DEVICE_CLASSES, + POWER_USAGE_UNITS, + POWER_UNIT_ERROR, + source_result, + ) + ) + + +def _validate_gas_source( + hass: HomeAssistant, + source: data.GasSourceType, + statistics_metadata: dict[str, tuple[int, recorder.models.StatisticMetaData]], + wanted_statistics_metadata: set[str], + source_result: ValidationIssues, + validate_calls: list[functools.partial[None]], +) -> None: + """Validate gas energy source.""" + wanted_statistics_metadata.add(source["stat_energy_from"]) + validate_calls.append( + functools.partial( + _async_validate_usage_stat, + hass, + statistics_metadata, + source["stat_energy_from"], + GAS_USAGE_DEVICE_CLASSES, + GAS_USAGE_UNITS, + GAS_UNIT_ERROR, + source_result, + ) + ) + + if (stat_cost := source.get("stat_cost")) is not None: + wanted_statistics_metadata.add(stat_cost) + validate_calls.append( + functools.partial( + _async_validate_cost_stat, + hass, + statistics_metadata, + stat_cost, + source_result, + ) + ) + elif (entity_energy_price := source.get("entity_energy_price")) is not None: + validate_calls.append( + functools.partial( + _async_validate_price_entity, + hass, + entity_energy_price, + source_result, + GAS_PRICE_UNITS, + GAS_PRICE_UNIT_ERROR, + ) + ) + + if ( + source.get("entity_energy_price") is not None + or source.get("number_energy_price") is not None + ): + validate_calls.append( + functools.partial( + _async_validate_auto_generated_cost_entity, + hass, + source["stat_energy_from"], + source_result, + ) + ) + + +def _validate_water_source( + hass: HomeAssistant, + source: data.WaterSourceType, + statistics_metadata: dict[str, tuple[int, recorder.models.StatisticMetaData]], + wanted_statistics_metadata: set[str], + source_result: ValidationIssues, + validate_calls: list[functools.partial[None]], +) -> None: + """Validate water energy source.""" + wanted_statistics_metadata.add(source["stat_energy_from"]) + validate_calls.append( + functools.partial( + _async_validate_usage_stat, + hass, + statistics_metadata, + source["stat_energy_from"], + WATER_USAGE_DEVICE_CLASSES, + WATER_USAGE_UNITS, + WATER_UNIT_ERROR, + source_result, + ) + ) + + if (stat_cost := source.get("stat_cost")) is not None: + wanted_statistics_metadata.add(stat_cost) + validate_calls.append( + functools.partial( + _async_validate_cost_stat, + hass, + statistics_metadata, + stat_cost, + source_result, + ) + ) + elif (entity_energy_price := source.get("entity_energy_price")) is not None: + validate_calls.append( + functools.partial( + _async_validate_price_entity, + hass, + entity_energy_price, + source_result, + WATER_PRICE_UNITS, + WATER_PRICE_UNIT_ERROR, + ) + ) + + if ( + source.get("entity_energy_price") is not None + or source.get("number_energy_price") is not None + ): + validate_calls.append( + functools.partial( + _async_validate_auto_generated_cost_entity, + hass, + source["stat_energy_from"], + source_result, + ) + ) + + async def async_validate(hass: HomeAssistant) -> EnergyPreferencesValidation: """Validate the energy configuration.""" manager: data.EnergyManager = await data.async_get_manager(hass) statistics_metadata: dict[str, tuple[int, recorder.models.StatisticMetaData]] = {} - validate_calls = [] + validate_calls: list[functools.partial[None]] = [] wanted_statistics_metadata: set[str] = set() result = EnergyPreferencesValidation() @@ -404,230 +653,35 @@ async def async_validate(hass: HomeAssistant) -> EnergyPreferencesValidation: result.energy_sources.append(source_result) if source["type"] == "grid": - flow: data.FlowFromGridSourceType | data.FlowToGridSourceType - for flow in source["flow_from"]: - wanted_statistics_metadata.add(flow["stat_energy_from"]) - validate_calls.append( - functools.partial( - _async_validate_usage_stat, - hass, - statistics_metadata, - flow["stat_energy_from"], - ENERGY_USAGE_DEVICE_CLASSES, - ENERGY_USAGE_UNITS, - ENERGY_UNIT_ERROR, - source_result, - ) - ) - - if (stat_cost := flow.get("stat_cost")) is not None: - wanted_statistics_metadata.add(stat_cost) - validate_calls.append( - functools.partial( - _async_validate_cost_stat, - hass, - statistics_metadata, - stat_cost, - source_result, - ) - ) - elif ( - entity_energy_price := flow.get("entity_energy_price") - ) is not None: - validate_calls.append( - functools.partial( - _async_validate_price_entity, - hass, - entity_energy_price, - source_result, - ENERGY_PRICE_UNITS, - ENERGY_PRICE_UNIT_ERROR, - ) - ) - - if ( - flow.get("entity_energy_price") is not None - or flow.get("number_energy_price") is not None - ): - validate_calls.append( - functools.partial( - _async_validate_auto_generated_cost_entity, - hass, - flow["stat_energy_from"], - source_result, - ) - ) - - for flow in source["flow_to"]: - wanted_statistics_metadata.add(flow["stat_energy_to"]) - validate_calls.append( - functools.partial( - _async_validate_usage_stat, - hass, - statistics_metadata, - flow["stat_energy_to"], - ENERGY_USAGE_DEVICE_CLASSES, - ENERGY_USAGE_UNITS, - ENERGY_UNIT_ERROR, - source_result, - ) - ) - - if (stat_compensation := flow.get("stat_compensation")) is not None: - wanted_statistics_metadata.add(stat_compensation) - validate_calls.append( - functools.partial( - _async_validate_cost_stat, - hass, - statistics_metadata, - stat_compensation, - source_result, - ) - ) - elif ( - entity_energy_price := flow.get("entity_energy_price") - ) is not None: - validate_calls.append( - functools.partial( - _async_validate_price_entity, - hass, - entity_energy_price, - source_result, - ENERGY_PRICE_UNITS, - ENERGY_PRICE_UNIT_ERROR, - ) - ) - - if ( - flow.get("entity_energy_price") is not None - or flow.get("number_energy_price") is not None - ): - validate_calls.append( - functools.partial( - _async_validate_auto_generated_cost_entity, - hass, - flow["stat_energy_to"], - source_result, - ) - ) - - for power_stat in source.get("power", []): - wanted_statistics_metadata.add(power_stat["stat_rate"]) - validate_calls.append( - functools.partial( - _async_validate_power_stat, - hass, - statistics_metadata, - power_stat["stat_rate"], - POWER_USAGE_DEVICE_CLASSES, - POWER_USAGE_UNITS, - POWER_UNIT_ERROR, - source_result, - ) - ) + _validate_grid_source( + hass, + source, + statistics_metadata, + wanted_statistics_metadata, + source_result, + validate_calls, + ) elif source["type"] == "gas": - wanted_statistics_metadata.add(source["stat_energy_from"]) - validate_calls.append( - functools.partial( - _async_validate_usage_stat, - hass, - statistics_metadata, - source["stat_energy_from"], - GAS_USAGE_DEVICE_CLASSES, - GAS_USAGE_UNITS, - GAS_UNIT_ERROR, - source_result, - ) + _validate_gas_source( + hass, + source, + statistics_metadata, + wanted_statistics_metadata, + source_result, + validate_calls, ) - if (stat_cost := source.get("stat_cost")) is not None: - wanted_statistics_metadata.add(stat_cost) - validate_calls.append( - functools.partial( - _async_validate_cost_stat, - hass, - statistics_metadata, - stat_cost, - source_result, - ) - ) - elif (entity_energy_price := source.get("entity_energy_price")) is not None: - validate_calls.append( - functools.partial( - _async_validate_price_entity, - hass, - entity_energy_price, - source_result, - GAS_PRICE_UNITS, - GAS_PRICE_UNIT_ERROR, - ) - ) - - if ( - source.get("entity_energy_price") is not None - or source.get("number_energy_price") is not None - ): - validate_calls.append( - functools.partial( - _async_validate_auto_generated_cost_entity, - hass, - source["stat_energy_from"], - source_result, - ) - ) - elif source["type"] == "water": - wanted_statistics_metadata.add(source["stat_energy_from"]) - validate_calls.append( - functools.partial( - _async_validate_usage_stat, - hass, - statistics_metadata, - source["stat_energy_from"], - WATER_USAGE_DEVICE_CLASSES, - WATER_USAGE_UNITS, - WATER_UNIT_ERROR, - source_result, - ) + _validate_water_source( + hass, + source, + statistics_metadata, + wanted_statistics_metadata, + source_result, + validate_calls, ) - if (stat_cost := source.get("stat_cost")) is not None: - wanted_statistics_metadata.add(stat_cost) - validate_calls.append( - functools.partial( - _async_validate_cost_stat, - hass, - statistics_metadata, - stat_cost, - source_result, - ) - ) - elif (entity_energy_price := source.get("entity_energy_price")) is not None: - validate_calls.append( - functools.partial( - _async_validate_price_entity, - hass, - entity_energy_price, - source_result, - WATER_PRICE_UNITS, - WATER_PRICE_UNIT_ERROR, - ) - ) - - if ( - source.get("entity_energy_price") is not None - or source.get("number_energy_price") is not None - ): - validate_calls.append( - functools.partial( - _async_validate_auto_generated_cost_entity, - hass, - source["stat_energy_from"], - source_result, - ) - ) - elif source["type"] == "solar": wanted_statistics_metadata.add(source["stat_energy_from"]) validate_calls.append(