Remove scan interval option from NUT (#141845)

Remove scan interval option and test case, migrate config and add migration test case
This commit is contained in:
tdfountain 2025-03-30 13:34:45 -07:00 committed by GitHub
parent 85d2e3d006
commit e81a08916a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 36 additions and 100 deletions

View File

@ -25,12 +25,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, HomeAssistantError
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import ( from .const import DOMAIN, INTEGRATION_SUPPORTED_COMMANDS, PLATFORMS
DEFAULT_SCAN_INTERVAL,
DOMAIN,
INTEGRATION_SUPPORTED_COMMANDS,
PLATFORMS,
)
NUT_FAKE_SERIAL = ["unknown", "blank"] NUT_FAKE_SERIAL = ["unknown", "blank"]
@ -68,7 +63,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: NutConfigEntry) -> bool:
alias = config.get(CONF_ALIAS) alias = config.get(CONF_ALIAS)
username = config.get(CONF_USERNAME) username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD) password = config.get(CONF_PASSWORD)
scan_interval = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL) if CONF_SCAN_INTERVAL in entry.options:
current_options = {**entry.options}
current_options.pop(CONF_SCAN_INTERVAL)
hass.config_entries.async_update_entry(entry, options=current_options)
data = PyNUTData(host, port, alias, username, password) data = PyNUTData(host, port, alias, username, password)
@ -101,7 +99,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NutConfigEntry) -> bool:
config_entry=entry, config_entry=entry,
name="NUT resource status", name="NUT resource status",
update_method=async_update_data, update_method=async_update_data,
update_interval=timedelta(seconds=scan_interval), update_interval=timedelta(seconds=60),
always_update=False, always_update=False,
) )

View File

@ -9,27 +9,21 @@ from typing import Any
from aionut import NUTError, NUTLoginError from aionut import NUTError, NUTLoginError
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ( from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
OptionsFlow,
)
from homeassistant.const import ( from homeassistant.const import (
CONF_ALIAS, CONF_ALIAS,
CONF_BASE, CONF_BASE,
CONF_HOST, CONF_HOST,
CONF_PASSWORD, CONF_PASSWORD,
CONF_PORT, CONF_PORT,
CONF_SCAN_INTERVAL,
CONF_USERNAME, CONF_USERNAME,
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import AbortFlow from homeassistant.data_entry_flow import AbortFlow
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
from . import PyNUTData from . import PyNUTData
from .const import DEFAULT_HOST, DEFAULT_PORT, DEFAULT_SCAN_INTERVAL, DOMAIN from .const import DEFAULT_HOST, DEFAULT_PORT, DOMAIN
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -230,32 +224,3 @@ class NutConfigFlow(ConfigFlow, domain=DOMAIN):
data_schema=vol.Schema(AUTH_SCHEMA), data_schema=vol.Schema(AUTH_SCHEMA),
errors=errors, errors=errors,
) )
@staticmethod
@callback
def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
"""Get the options flow for this handler."""
return OptionsFlowHandler()
class OptionsFlowHandler(OptionsFlow):
"""Handle a option flow for nut."""
async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle options flow."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)
scan_interval = self.config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
)
base_schema = {
vol.Optional(CONF_SCAN_INTERVAL, default=scan_interval): vol.All(
vol.Coerce(int), vol.Clamp(min=10, max=300)
)
}
return self.async_show_form(step_id="init", data_schema=vol.Schema(base_schema))

View File

@ -19,8 +19,6 @@ DEFAULT_PORT = 3493
KEY_STATUS = "ups.status" KEY_STATUS = "ups.status"
KEY_STATUS_DISPLAY = "ups.status.display" KEY_STATUS_DISPLAY = "ups.status.display"
DEFAULT_SCAN_INTERVAL = 60
STATE_TYPES = { STATE_TYPES = {
"OL": "Online", "OL": "Online",
"OB": "On Battery", "OB": "On Battery",

View File

@ -38,15 +38,6 @@
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
} }
}, },
"options": {
"step": {
"init": {
"data": {
"scan_interval": "Scan Interval (seconds)"
}
}
}
},
"device_automation": { "device_automation": {
"action_type": { "action_type": {
"beeper_disable": "Disable UPS beeper/buzzer", "beeper_disable": "Disable UPS beeper/buzzer",

View File

@ -14,7 +14,6 @@ from homeassistant.const import (
CONF_PASSWORD, CONF_PASSWORD,
CONF_PORT, CONF_PORT,
CONF_RESOURCES, CONF_RESOURCES,
CONF_SCAN_INTERVAL,
CONF_USERNAME, CONF_USERNAME,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -573,45 +572,3 @@ async def test_abort_if_already_setup_alias(hass: HomeAssistant) -> None:
assert result3["type"] is FlowResultType.ABORT assert result3["type"] is FlowResultType.ABORT
assert result3["reason"] == "already_configured" assert result3["reason"] == "already_configured"
async def test_options_flow(hass: HomeAssistant) -> None:
"""Test config flow options."""
config_entry = MockConfigEntry(
domain=DOMAIN,
unique_id="abcde12345",
data=VALID_CONFIG,
)
config_entry.add_to_hass(hass)
with patch("homeassistant.components.nut.async_setup_entry", return_value=True):
result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "init"
result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert config_entry.options == {
CONF_SCAN_INTERVAL: 60,
}
with patch("homeassistant.components.nut.async_setup_entry", return_value=True):
result2 = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result2["type"] is FlowResultType.FORM
assert result2["step_id"] == "init"
result2 = await hass.config_entries.options.async_configure(
result2["flow_id"],
user_input={CONF_SCAN_INTERVAL: 12},
)
assert result2["type"] is FlowResultType.CREATE_ENTRY
assert config_entry.options == {
CONF_SCAN_INTERVAL: 12,
}

View File

@ -12,6 +12,7 @@ from homeassistant.const import (
CONF_HOST, CONF_HOST,
CONF_PASSWORD, CONF_PASSWORD,
CONF_PORT, CONF_PORT,
CONF_SCAN_INTERVAL,
CONF_USERNAME, CONF_USERNAME,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
) )
@ -23,6 +24,32 @@ from .util import _get_mock_nutclient, async_init_integration
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
async def test_config_entry_migrations(hass: HomeAssistant) -> None:
"""Test that config entries were migrated."""
mock_pynut = _get_mock_nutclient(
list_vars={"battery.voltage": "voltage"},
list_ups={"ups1": "UPS 1"},
)
with patch(
"homeassistant.components.nut.AIONUTClient",
return_value=mock_pynut,
):
entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_HOST: "1.1.1.1",
CONF_PORT: 123,
},
options={CONF_SCAN_INTERVAL: 30},
)
entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(entry.entry_id)
assert CONF_SCAN_INTERVAL not in entry.options
async def test_async_setup_entry(hass: HomeAssistant) -> None: async def test_async_setup_entry(hass: HomeAssistant) -> None:
"""Test a successful setup entry.""" """Test a successful setup entry."""
entry = MockConfigEntry( entry = MockConfigEntry(