Skip to content

Commit

Permalink
provide different step for utility meter options in GUI config (#2100)
Browse files Browse the repository at this point in the history
  • Loading branch information
bramstroker committed Mar 3, 2024
1 parent cab08c9 commit 7e1a284
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 12 deletions.
43 changes: 39 additions & 4 deletions custom_components/powercalc/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.components.sensor import SensorDeviceClass
from homeassistant.components.utility_meter import CONF_METER_TYPE, METER_TYPES
from homeassistant.config_entries import ConfigEntry, OptionsFlow
from homeassistant.const import (
CONF_ATTRIBUTE,
Expand Down Expand Up @@ -68,6 +69,7 @@
CONF_UNAVAILABLE_POWER,
CONF_UPDATE_FREQUENCY,
CONF_UTILITY_METER_TARIFFS,
CONF_UTILITY_METER_TYPES,
CONF_VALUE,
CONF_VALUE_TEMPLATE,
CONF_WLED,
Expand Down Expand Up @@ -132,9 +134,6 @@
CONF_CREATE_UTILITY_METERS,
default=False,
): selector.BooleanSelector(),
vol.Optional(CONF_UTILITY_METER_TARIFFS, default=[]): selector.SelectSelector(
selector.SelectSelectorConfig(options=[], custom_value=True, multiple=True),
),
},
)
SCHEMA_DAILY_ENERGY = vol.Schema(
Expand All @@ -149,11 +148,11 @@
vol.Required(CONF_ENTITY_ID): selector.EntitySelector(
selector.EntitySelectorConfig(device_class=SensorDeviceClass.POWER),
),
vol.Optional(CONF_DEVICE): selector.DeviceSelector(),
vol.Optional(
CONF_CREATE_UTILITY_METERS,
default=False,
): selector.BooleanSelector(),
vol.Optional(CONF_DEVICE): selector.DeviceSelector(),
},
)

Expand Down Expand Up @@ -265,6 +264,19 @@
},
)

SCHEMA_UTILITY_METER_OPTIONS = vol.Schema(
{
vol.Optional(CONF_UTILITY_METER_TARIFFS, default=[]): selector.SelectSelector(
selector.SelectSelectorConfig(options=[], custom_value=True, multiple=True),
),
vol.Optional(CONF_UTILITY_METER_TYPES): selector.SelectSelector(
selector.SelectSelectorConfig(
options=METER_TYPES, translation_key=CONF_METER_TYPE, multiple=True,
),
),
},
)


class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for PowerCalc."""
Expand Down Expand Up @@ -424,6 +436,8 @@ async def async_step_daily_energy(
self._abort_if_unique_id_configured()

self.sensor_config.update(_build_daily_energy_config(user_input))
if self.sensor_config.get(CONF_CREATE_UTILITY_METERS):
return await self.async_step_utility_meter_options()
return self.create_config_entry()

return self.async_show_form(
Expand All @@ -447,6 +461,8 @@ async def async_step_group(
self._abort_if_unique_id_configured()

if not errors:
if self.sensor_config.get(CONF_CREATE_UTILITY_METERS):
return await self.async_step_utility_meter_options()
return self.create_config_entry()

group_schema = SCHEMA_GROUP.extend(
Expand Down Expand Up @@ -600,6 +616,8 @@ async def async_step_real_power(
if user_input is not None:
self.name = user_input.get(CONF_NAME)
self.sensor_config.update(user_input)
if self.sensor_config.get(CONF_CREATE_UTILITY_METERS):
return await self.async_step_utility_meter_options()
return self.create_config_entry()

return self.async_show_form(
Expand Down Expand Up @@ -717,6 +735,23 @@ async def async_step_power_advanced(
errors={},
)

async def async_step_utility_meter_options(
self,
user_input: dict[str, Any] | None = None,
) -> FlowResult:
if user_input is not None:
self.sensor_config.update(user_input or {})
return self.create_config_entry()

return self.async_show_form(
step_id="utility_meter_options",
data_schema=_fill_schema_defaults(
SCHEMA_UTILITY_METER_OPTIONS,
_get_global_powercalc_config(self.hass),
),
errors={},
)

async def validate_strategy_config(self) -> dict:
strategy_name = (
self.sensor_config.get(CONF_MODE) or self.power_profile.calculation_strategy # type: ignore
Expand Down
18 changes: 14 additions & 4 deletions custom_components/powercalc/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
"unit_of_measurement": "Unit of measurement",
"update_frequency": "Update frequency",
"value": "Value",
"value_template": "Value template",
"utility_meter_tariffs": "Utility meter tariffs"
"value_template": "Value template"
},
"data_description": {
"on_time": "When left empty defaults to 1 day. always on",
Expand Down Expand Up @@ -73,8 +72,7 @@
"group_member_sensors": "Powercalc sensors to include in the group",
"group_power_entities": "Additional power sensors (W) from your HA installation to include",
"sub_groups": "All containing sensors from the selected subgroups will be added to this group as well",
"include_non_powercalc_sensors": "Control whether to include non powercalc sensors when using the area option",
"utility_meter_tariffs": "A list of supported tariffs, leave empty if only a single tariff is needed."
"include_non_powercalc_sensors": "Control whether to include non powercalc sensors when using the area option"
},
"title": "Create a group sensor"
},
Expand Down Expand Up @@ -185,6 +183,18 @@
},
"title": "Choose your sensor type"
},
"utility_meter_options": {
"title": "Utility meter options",
"description": "Define the settings for utility meter creation here",
"data": {
"utility_meter_types": "Cycles",
"utility_meter_tariffs": "Tariffs"
},
"data_description": {
"utility_meter_types": "Create utility meters for specified cycles",
"utility_meter_tariffs": "A list of supported tariffs, leave empty if only a single tariff is needed."
}
},
"virtual_power": {
"data": {
"create_energy_sensor": "Create energy sensor",
Expand Down
2 changes: 0 additions & 2 deletions tests/config_flow/test_daily_energy.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
CONF_ON_TIME,
CONF_SENSOR_TYPE,
CONF_UPDATE_FREQUENCY,
CONF_UTILITY_METER_TARIFFS,
CONF_VALUE,
)
from tests.config_flow.common import (
Expand Down Expand Up @@ -61,7 +60,6 @@ async def test_create_daily_energy_entry(hass: HomeAssistant) -> None:
CONF_UPDATE_FREQUENCY: 1800,
CONF_VALUE: 0.5,
CONF_UNIT_OF_MEASUREMENT: UnitOfPower.WATT,
CONF_UTILITY_METER_TARIFFS: [],
},
CONF_CREATE_UTILITY_METERS: False,
CONF_UNIQUE_ID: DEFAULT_UNIQUE_ID,
Expand Down
9 changes: 9 additions & 0 deletions tests/config_flow/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
CONF_POWER,
CONF_STATES_POWER,
CONF_SUB_GROUPS,
CONF_UTILITY_METER_TARIFFS,
DOMAIN,
CalculationStrategy,
)
Expand Down Expand Up @@ -131,6 +132,13 @@ async def test_group_include_area(
result["flow_id"],
user_input,
)

# Submit utility_meter_options step with default settings
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{},
)

assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
assert result["data"] == {
CONF_SENSOR_TYPE: SensorType.GROUP,
Expand All @@ -140,6 +148,7 @@ async def test_group_include_area(
CONF_UNIQUE_ID: "My group sensor",
CONF_INCLUDE_NON_POWERCALC_SENSORS: True,
CONF_CREATE_UTILITY_METERS: True,
CONF_UTILITY_METER_TARIFFS: [],
}

hass.states.async_set("sensor.test_power", 5)
Expand Down
45 changes: 43 additions & 2 deletions tests/config_flow/test_real_power.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from homeassistant import data_entry_flow
from homeassistant.components.utility_meter.const import DAILY, WEEKLY
from homeassistant.const import CONF_DEVICE, CONF_ENTITY_ID, CONF_NAME, CONF_SENSOR_TYPE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntry
Expand All @@ -8,7 +9,7 @@
mock_registry,
)

from custom_components.powercalc import CONF_CREATE_UTILITY_METERS, SensorType
from custom_components.powercalc import CONF_CREATE_UTILITY_METERS, CONF_UTILITY_METER_TARIFFS, CONF_UTILITY_METER_TYPES, SensorType
from tests.config_flow.common import (
create_mock_entry,
initialize_options_flow,
Expand All @@ -28,6 +29,13 @@ async def test_real_power(hass: HomeAssistant) -> None:
CONF_CREATE_UTILITY_METERS: True,
},
)

# Submit utility meter options step with default settings
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{},
)

assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY

await hass.async_block_till_done()
Expand Down Expand Up @@ -69,7 +77,7 @@ async def test_energy_sensor_is_bound_to_power_device(hass: HomeAssistant) -> No
{
CONF_NAME: "Test",
CONF_ENTITY_ID: power_sensor_id,
CONF_CREATE_UTILITY_METERS: True,
CONF_CREATE_UTILITY_METERS: False,
},
)
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
Expand Down Expand Up @@ -173,3 +181,36 @@ async def test_no_error_is_raised_when_device_not_exists(hass: HomeAssistant) ->
await hass.async_block_till_done()

assert hass.states.get("sensor.test_energy")


async def test_create_utility_meter_tariff_sensors(hass: HomeAssistant) -> None:
result = await select_sensor_type(hass, SensorType.REAL_POWER)

result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_NAME: "Test",
CONF_ENTITY_ID: "sensor.my_smart_plug",
CONF_CREATE_UTILITY_METERS: True,
},
)

assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "utility_meter_options"

await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_UTILITY_METER_TARIFFS: ["peak", "offpeak"],
CONF_UTILITY_METER_TYPES: [DAILY, WEEKLY],
},
)

await hass.async_block_till_done()

assert hass.states.get("sensor.test_energy")
assert hass.states.get("select.test_energy_daily")
assert hass.states.get("sensor.test_energy_daily_peak")
assert hass.states.get("sensor.test_energy_daily_offpeak")
assert hass.states.get("sensor.test_energy_weekly_peak")
assert hass.states.get("sensor.test_energy_weekly_offpeak")

0 comments on commit 7e1a284

Please sign in to comment.