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

Minor fixes in GUI options flow for smart switches #1345

Merged
merged 9 commits into from
Dec 4, 2022
39 changes: 14 additions & 25 deletions custom_components/powercalc/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,16 +553,9 @@ async def async_step_power_advanced(
)

async def validate_strategy_config(self) -> dict:
strategy_name = (
self.sensor_config.get(CONF_MODE)
or self.power_profile.supported_strategies[0]
)
strategy_name = self.sensor_config.get(CONF_MODE) or self.power_profile.supported_strategies[0]
strategy = await _create_strategy_object(
self.hass,
strategy_name,
self.sensor_config,
self.source_entity,
self.power_profile,
self.hass, strategy_name, self.sensor_config, self.source_entity, self.power_profile
)
try:
await strategy.validate_config()
Expand Down Expand Up @@ -600,12 +593,15 @@ def __init__(self, config_entry: ConfigEntry) -> None:
)
self.source_entity_id: str | None = self.current_config.get(CONF_ENTITY_ID)
self.source_entity: SourceEntity | None = None
self.power_profile: PowerProfile | None = None
self.strategy: CalculationStrategy | None = self.current_config.get(CONF_MODE)

async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle options flow."""

errors = {}
self.current_config = dict(self.config_entry.data)
if self.source_entity_id:
self.source_entity = await create_source_entity(
Expand All @@ -625,7 +621,6 @@ async def async_step_init(
except ModelNotSupported:
errors["not_supported"] = "Power profile could not be loaded"

errors = {}
if user_input is not None:
errors = await self.save_options(user_input)
if not errors:
Expand Down Expand Up @@ -656,17 +651,16 @@ async def save_options(self, user_input: dict[str, Any] | None = None) -> dict:

self.current_config.update(generic_options)

strategy = self.current_config.get(CONF_MODE)
if strategy:
if self.strategy:
strategy_options = _build_strategy_config(
strategy, self.source_entity_id, user_input
self.strategy, self.source_entity_id, user_input
)

if strategy != CalculationStrategy.LUT:
self.current_config.update({strategy: strategy_options})
if self.strategy != CalculationStrategy.LUT:
self.current_config.update({self.strategy: strategy_options})

strategy_object = await _create_strategy_object(
self.hass, strategy, self.current_config, self.source_entity
self.hass, self.strategy, self.current_config, self.source_entity
)
try:
await strategy_object.validate_config()
Expand All @@ -687,15 +681,14 @@ def build_options_schema(self) -> vol.Schema:
strategy_options = {}
data_schema = {}
if self.sensor_type == SensorType.VIRTUAL_POWER:
strategy: str = self.current_config.get(CONF_MODE)
if strategy:
strategy_schema = _get_strategy_schema(strategy, self.source_entity_id)
if self.strategy:
strategy_schema = _get_strategy_schema(self.strategy, self.source_entity_id)
else:
strategy_schema = vol.Schema({})
data_schema = SCHEMA_POWER_OPTIONS.extend(strategy_schema.schema).extend(
SCHEMA_POWER_ADVANCED.schema
)
strategy_options = self.current_config.get(strategy) or {}
strategy_options = self.current_config.get(self.strategy) or {}

if self.sensor_type == SensorType.DAILY_ENERGY:
data_schema = SCHEMA_DAILY_ENERGY_OPTIONS
Expand All @@ -711,11 +704,7 @@ def build_options_schema(self) -> vol.Schema:


async def _create_strategy_object(
hass: HomeAssistant,
strategy: str,
config: dict,
source_entity: SourceEntity,
power_profile: PowerProfile | None = None,
hass: HomeAssistant, strategy: str, config: dict, source_entity: SourceEntity, power_profile: PowerProfile | None = None
) -> PowerCalculationStrategyInterface:
"""Create the calculation strategy object"""
factory = PowerCalculatorStrategyFactory(hass)
Expand Down
6 changes: 2 additions & 4 deletions custom_components/powercalc/power_profile/power_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from homeassistant.helpers.typing import ConfigType

from ..common import SourceEntity
from ..const import CONF_POWER, CalculationStrategy
from ..const import CalculationStrategy, CONF_POWER
from ..errors import ModelNotSupported, PowercalcSetupError, UnsupportedStrategy

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -162,9 +162,7 @@ def needs_fixed_config(self) -> bool:
Used for smart switches which only provides standby power values.
This indicates the user must supply the power values in the config flow
"""
return self.is_strategy_supported(
CalculationStrategy.FIXED
) and not self._json_data.get("fixed_config")
return self.is_strategy_supported(CalculationStrategy.FIXED) and not self._json_data.get("fixed_config")

@property
def device_type(self) -> DeviceType:
Expand Down
33 changes: 30 additions & 3 deletions tests/power_profile/device_types/test_smart_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntry
from homeassistant.helpers.entity_registry import RegistryEntry
from homeassistant.data_entry_flow import FlowResultType
from pytest_homeassistant_custom_component.common import (
mock_device_registry,
mock_registry,
)

from custom_components.powercalc.config_flow import CONF_CONFIRM_AUTODISCOVERED_MODEL
from custom_components.powercalc.const import (
CONF_CUSTOM_MODEL_DIRECTORY,
Expand Down Expand Up @@ -113,7 +113,9 @@ async def test_smart_switch_power_input_yaml(hass: HomeAssistant):
CONF_MANUFACTURER: manufacturer,
CONF_MODEL: model,
CONF_CUSTOM_MODEL_DIRECTORY: get_test_profile_dir("smart_switch"),
CONF_FIXED: {CONF_POWER: 50},
CONF_FIXED: {
CONF_POWER: 50
}
},
)

Expand Down Expand Up @@ -177,8 +179,16 @@ async def test_smart_switch_power_input_gui_config_flow(hass: HomeAssistant):

# After confirming the manufacturer/model we must be directed to the fixed config step
assert result["step_id"] == "fixed"
await hass.config_entries.flow.async_configure(flow["flow_id"], {CONF_POWER: 50})
result = await hass.config_entries.flow.async_configure(
flow["flow_id"], {CONF_POWER: 50}
)
assert result["type"] == FlowResultType.CREATE_ENTRY

entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1
config_entry = entries[0]

# Toggle the switch to different states and check for correct power values
power_state = hass.states.get(power_sensor_id)
assert power_state
assert power_state.state == "unavailable"
Expand All @@ -192,3 +202,20 @@ async def test_smart_switch_power_input_gui_config_flow(hass: HomeAssistant):
await hass.async_block_till_done()

assert hass.states.get(power_sensor_id).state == "0.40"

# Change the power value via the options
result = await hass.config_entries.options.async_init(
config_entry.entry_id,
data=None,
)
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_POWER: 100},
)
assert result["type"] == FlowResultType.CREATE_ENTRY

# Set the switch on again and see if it has the updated power value
hass.states.async_set(switch_id, STATE_ON)
await hass.async_block_till_done()

assert hass.states.get(power_sensor_id).state == "100.80"
6 changes: 5 additions & 1 deletion tests/sensors/test_energy.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
CONF_POWER_SENSOR_ID,
)

from ..common import create_input_boolean, get_simple_fixed_config, run_powercalc_setup
from ..common import (
create_input_boolean,
get_simple_fixed_config,
run_powercalc_setup,
)


async def test_related_energy_sensor_is_used_for_existing_power_sensor(
Expand Down