Restore ability to change the scan interval in the NUT (#33996)

* Support changing the scan interval in the NUT options flow

* use dict.items()
This commit is contained in:
J. Nick Koston 2020-04-11 19:37:34 -05:00 committed by GitHub
parent e3f47beda4
commit 24c45bfd84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 106 additions and 65 deletions

View File

@ -1,49 +1,46 @@
{ {
"config": { "config": {
"abort": { "title": "Network UPS Tools (NUT)",
"already_configured": "Device is already configured" "step": {
"user": {
"title": "Connect to the NUT server",
"data": {
"host": "Host",
"port": "Port",
"username": "Username",
"password": "Password"
}
},
"ups": {
"title": "Choose the UPS to Monitor",
"data": {
"alias": "Alias",
"resources": "Resources"
}
},
"resources": {
"title": "Choose the Resources to Monitor",
"data": {
"resources": "Resources"
}
}
}, },
"error": { "error": {
"cannot_connect": "Failed to connect, please try again", "cannot_connect": "Failed to connect, please try again",
"unknown": "Unexpected error" "unknown": "Unexpected error"
}, },
"step": { "abort": {
"resources": { "already_configured": "Device is already configured"
"data": {
"resources": "Resources"
},
"title": "Choose the Resources to Monitor"
},
"ups": {
"data": {
"alias": "Alias",
"resources": "Resources"
},
"title": "Choose the UPS to Monitor"
},
"user": {
"data": {
"alias": "Alias",
"host": "Host",
"name": "Name",
"password": "Password",
"port": "Port",
"resources": "Resources",
"username": "Username"
},
"description": "If there are multiple UPSs attached to the NUT server, enter the name UPS to query in the 'Alias' field.",
"title": "Connect to the NUT server"
} }
}, },
"title": "Network UPS Tools (NUT)"
},
"options": { "options": {
"step": { "step": {
"init": { "init": {
"description": "Choose Sensor Resources.",
"data": { "data": {
"resources": "Resources" "resources": "Resources",
}, "scan_interval": "Scan Interval (seconds)"
"description": "Choose Sensor Resources." }
} }
} }
} }

View File

@ -13,6 +13,7 @@ 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
@ -21,6 +22,7 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import ( from .const import (
COORDINATOR, COORDINATOR,
DEFAULT_SCAN_INTERVAL,
DOMAIN, DOMAIN,
PLATFORMS, PLATFORMS,
PYNUT_DATA, PYNUT_DATA,
@ -52,6 +54,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
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)
data = PyNUTData(host, port, alias, username, password) data = PyNUTData(host, port, alias, username, password)
@ -65,7 +68,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
_LOGGER, _LOGGER,
name="NUT resource status", name="NUT resource status",
update_method=async_update_data, update_method=async_update_data,
update_interval=timedelta(seconds=60), update_interval=timedelta(seconds=scan_interval),
) )
# Fetch initial data so we have data when entities subscribe # Fetch initial data so we have data when entities subscribe

View File

@ -10,19 +10,29 @@ 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 callback from homeassistant.core import callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from . import PyNUTData, find_resources_in_config_entry from . import PyNUTData, find_resources_in_config_entry
from .const import DEFAULT_HOST, DEFAULT_PORT, SENSOR_TYPES from .const import (
DEFAULT_HOST,
DEFAULT_PORT,
DEFAULT_SCAN_INTERVAL,
SENSOR_NAME,
SENSOR_TYPES,
)
from .const import DOMAIN # pylint:disable=unused-import from .const import DOMAIN # pylint:disable=unused-import
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
SENSOR_DICT = {sensor_id: SENSOR_TYPES[sensor_id][0] for sensor_id in SENSOR_TYPES} SENSOR_DICT = {
sensor_id: sensor_spec[SENSOR_NAME]
for sensor_id, sensor_spec in SENSOR_TYPES.items()
}
DATA_SCHEMA = vol.Schema( DATA_SCHEMA = vol.Schema(
{ {
@ -34,22 +44,20 @@ DATA_SCHEMA = vol.Schema(
) )
def _resource_schema(available_resources, selected_resources): def _resource_schema_base(available_resources, selected_resources):
"""Resource selection schema.""" """Resource selection schema."""
known_available_resources = { known_available_resources = {
sensor_id: sensor[0] sensor_id: sensor[SENSOR_NAME]
for sensor_id, sensor in SENSOR_TYPES.items() for sensor_id, sensor in SENSOR_TYPES.items()
if sensor_id in available_resources if sensor_id in available_resources
} }
return vol.Schema( return {
{
vol.Required(CONF_RESOURCES, default=selected_resources): cv.multi_select( vol.Required(CONF_RESOURCES, default=selected_resources): cv.multi_select(
known_available_resources known_available_resources
) )
} }
)
def _ups_schema(ups_list): def _ups_schema(ups_list):
@ -160,7 +168,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
if user_input is None: if user_input is None:
return self.async_show_form( return self.async_show_form(
step_id="resources", step_id="resources",
data_schema=_resource_schema(self.available_resources, []), data_schema=vol.Schema(
_resource_schema_base(self.available_resources, [])
),
) )
self.nut_config.update(user_input) self.nut_config.update(user_input)
@ -207,12 +217,19 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
return self.async_create_entry(title="", data=user_input) return self.async_create_entry(title="", data=user_input)
resources = find_resources_in_config_entry(self.config_entry) resources = find_resources_in_config_entry(self.config_entry)
scan_interval = self.config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
)
info = await validate_input(self.hass, self.config_entry.data) info = await validate_input(self.hass, self.config_entry.data)
base_schema = _resource_schema_base(info["available_resources"], resources)
base_schema[
vol.Optional(CONF_SCAN_INTERVAL, default=scan_interval)
] = cv.positive_int
return self.async_show_form( return self.async_show_form(
step_id="init", step_id="init", data_schema=vol.Schema(base_schema),
data_schema=_resource_schema(info["available_resources"], resources),
) )

View File

@ -26,6 +26,7 @@ KEY_STATUS = "ups.status"
KEY_STATUS_DISPLAY = "ups.status.display" KEY_STATUS_DISPLAY = "ups.status.display"
COORDINATOR = "coordinator" COORDINATOR = "coordinator"
DEFAULT_SCAN_INTERVAL = 60
PYNUT_DATA = "data" PYNUT_DATA = "data"
PYNUT_UNIQUE_ID = "unique_id" PYNUT_UNIQUE_ID = "unique_id"

View File

@ -38,7 +38,8 @@
"init": { "init": {
"description": "Choose Sensor Resources.", "description": "Choose Sensor Resources.",
"data": { "data": {
"resources": "Resources" "resources": "Resources",
"scan_interval": "Scan Interval (seconds)"
} }
} }
} }

View File

@ -3,7 +3,7 @@ from asynctest import patch
from homeassistant import config_entries, data_entry_flow, setup from homeassistant import config_entries, data_entry_flow, setup
from homeassistant.components.nut.const import DOMAIN from homeassistant.components.nut.const import DOMAIN
from homeassistant.const import CONF_RESOURCES from homeassistant.const import CONF_RESOURCES, CONF_SCAN_INTERVAL
from .util import _get_mock_pynutclient from .util import _get_mock_pynutclient
@ -244,4 +244,26 @@ async def test_options_flow(hass):
) )
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {CONF_RESOURCES: ["battery.voltage"]} assert config_entry.options == {
CONF_RESOURCES: ["battery.voltage"],
CONF_SCAN_INTERVAL: 60,
}
with patch(
"homeassistant.components.nut.PyNUTClient", return_value=mock_pynut,
), 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"] == data_entry_flow.RESULT_TYPE_FORM
assert result2["step_id"] == "init"
result2 = await hass.config_entries.options.async_configure(
result2["flow_id"],
user_input={CONF_RESOURCES: ["battery.voltage"], CONF_SCAN_INTERVAL: 12},
)
assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert config_entry.options == {
CONF_RESOURCES: ["battery.voltage"],
CONF_SCAN_INTERVAL: 12,
}