Fix RainMachine not properly storing data in the config entry (#33002)

* Fix bug related to RainMachine's default config flow

* A

* Fix tests

* Code review
This commit is contained in:
Aaron Bach 2020-03-19 21:54:41 -06:00 committed by GitHub
parent c3c5cc9ae7
commit d8e3e9abaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 18 deletions

View file

@ -25,6 +25,7 @@ from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.service import verify_domain_control from homeassistant.helpers.service import verify_domain_control
from .const import ( from .const import (
CONF_ZONE_RUN_TIME,
DATA_CLIENT, DATA_CLIENT,
DATA_PROGRAMS, DATA_PROGRAMS,
DATA_PROVISION_SETTINGS, DATA_PROVISION_SETTINGS,
@ -33,6 +34,8 @@ from .const import (
DATA_ZONES, DATA_ZONES,
DATA_ZONES_DETAILS, DATA_ZONES_DETAILS,
DEFAULT_PORT, DEFAULT_PORT,
DEFAULT_SCAN_INTERVAL,
DEFAULT_ZONE_RUN,
DOMAIN, DOMAIN,
PROGRAM_UPDATE_TOPIC, PROGRAM_UPDATE_TOPIC,
SENSOR_UPDATE_TOPIC, SENSOR_UPDATE_TOPIC,
@ -41,19 +44,14 @@ from .const import (
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DATA_LISTENER = "listener"
CONF_CONTROLLERS = "controllers" CONF_CONTROLLERS = "controllers"
CONF_PROGRAM_ID = "program_id" CONF_PROGRAM_ID = "program_id"
CONF_SECONDS = "seconds" CONF_SECONDS = "seconds"
CONF_ZONE_ID = "zone_id" CONF_ZONE_ID = "zone_id"
CONF_ZONE_RUN_TIME = "zone_run_time"
DEFAULT_ATTRIBUTION = "Data provided by Green Electronics LLC" DEFAULT_ATTRIBUTION = "Data provided by Green Electronics LLC"
DEFAULT_ICON = "mdi:water" DEFAULT_ICON = "mdi:water"
DEFAULT_SCAN_INTERVAL = timedelta(seconds=60)
DEFAULT_SSL = True DEFAULT_SSL = True
DEFAULT_ZONE_RUN = 60 * 10
SERVICE_ALTER_PROGRAM = vol.Schema({vol.Required(CONF_PROGRAM_ID): cv.positive_int}) SERVICE_ALTER_PROGRAM = vol.Schema({vol.Required(CONF_PROGRAM_ID): cv.positive_int})
@ -109,7 +107,6 @@ async def async_setup(hass, config):
"""Set up the RainMachine component.""" """Set up the RainMachine component."""
hass.data[DOMAIN] = {} hass.data[DOMAIN] = {}
hass.data[DOMAIN][DATA_CLIENT] = {} hass.data[DOMAIN][DATA_CLIENT] = {}
hass.data[DOMAIN][DATA_LISTENER] = {}
if DOMAIN not in config: if DOMAIN not in config:
return True return True
@ -143,7 +140,7 @@ async def async_setup_entry(hass, config_entry):
config_entry.data[CONF_IP_ADDRESS], config_entry.data[CONF_IP_ADDRESS],
config_entry.data[CONF_PASSWORD], config_entry.data[CONF_PASSWORD],
port=config_entry.data[CONF_PORT], port=config_entry.data[CONF_PORT],
ssl=config_entry.data[CONF_SSL], ssl=config_entry.data.get(CONF_SSL, DEFAULT_SSL),
) )
except RainMachineError as err: except RainMachineError as err:
_LOGGER.error("An error occurred: %s", err) _LOGGER.error("An error occurred: %s", err)
@ -156,8 +153,10 @@ async def async_setup_entry(hass, config_entry):
rainmachine = RainMachine( rainmachine = RainMachine(
hass, hass,
controller, controller,
config_entry.data[CONF_ZONE_RUN_TIME], config_entry.data.get(CONF_ZONE_RUN_TIME, DEFAULT_ZONE_RUN),
config_entry.data[CONF_SCAN_INTERVAL], config_entry.data.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL.total_seconds()
),
) )
# Update the data object, which at this point (prior to any sensors registering # Update the data object, which at this point (prior to any sensors registering
@ -260,9 +259,6 @@ async def async_unload_entry(hass, config_entry):
"""Unload an OpenUV config entry.""" """Unload an OpenUV config entry."""
hass.data[DOMAIN][DATA_CLIENT].pop(config_entry.entry_id) hass.data[DOMAIN][DATA_CLIENT].pop(config_entry.entry_id)
remove_listener = hass.data[DOMAIN][DATA_LISTENER].pop(config_entry.entry_id)
remove_listener()
tasks = [ tasks = [
hass.config_entries.async_forward_entry_unload(config_entry, component) hass.config_entries.async_forward_entry_unload(config_entry, component)
for component in ("binary_sensor", "sensor", "switch") for component in ("binary_sensor", "sensor", "switch")

View file

@ -4,10 +4,22 @@ from regenmaschine.errors import RainMachineError
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.const import CONF_IP_ADDRESS, CONF_PASSWORD, CONF_PORT from homeassistant.const import (
CONF_IP_ADDRESS,
CONF_PASSWORD,
CONF_PORT,
CONF_SCAN_INTERVAL,
CONF_SSL,
)
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
from .const import DEFAULT_PORT, DOMAIN # pylint: disable=unused-import from .const import ( # pylint: disable=unused-import
CONF_ZONE_RUN_TIME,
DEFAULT_PORT,
DEFAULT_SCAN_INTERVAL,
DEFAULT_ZONE_RUN,
DOMAIN,
)
class RainMachineFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): class RainMachineFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
@ -53,8 +65,8 @@ class RainMachineFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
user_input[CONF_IP_ADDRESS], user_input[CONF_IP_ADDRESS],
user_input[CONF_PASSWORD], user_input[CONF_PASSWORD],
websession, websession,
port=user_input.get(CONF_PORT, DEFAULT_PORT), port=user_input[CONF_PORT],
ssl=True, ssl=user_input.get(CONF_SSL, True),
) )
except RainMachineError: except RainMachineError:
return await self._show_form({CONF_PASSWORD: "invalid_credentials"}) return await self._show_form({CONF_PASSWORD: "invalid_credentials"})
@ -63,5 +75,17 @@ class RainMachineFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
# access token without using the IP address and password, so we have to # access token without using the IP address and password, so we have to
# store it: # store it:
return self.async_create_entry( return self.async_create_entry(
title=user_input[CONF_IP_ADDRESS], data=user_input title=user_input[CONF_IP_ADDRESS],
data={
CONF_IP_ADDRESS: user_input[CONF_IP_ADDRESS],
CONF_PASSWORD: user_input[CONF_PASSWORD],
CONF_PORT: user_input[CONF_PORT],
CONF_SSL: user_input.get(CONF_SSL, True),
CONF_SCAN_INTERVAL: user_input.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL.total_seconds()
),
CONF_ZONE_RUN_TIME: user_input.get(
CONF_ZONE_RUN_TIME, DEFAULT_ZONE_RUN
),
},
) )

View file

@ -1,6 +1,10 @@
"""Define constants for the SimpliSafe component.""" """Define constants for the SimpliSafe component."""
from datetime import timedelta
DOMAIN = "rainmachine" DOMAIN = "rainmachine"
CONF_ZONE_RUN_TIME = "zone_run_time"
DATA_CLIENT = "client" DATA_CLIENT = "client"
DATA_PROGRAMS = "programs" DATA_PROGRAMS = "programs"
DATA_PROVISION_SETTINGS = "provision.settings" DATA_PROVISION_SETTINGS = "provision.settings"
@ -10,6 +14,8 @@ DATA_ZONES = "zones"
DATA_ZONES_DETAILS = "zones_details" DATA_ZONES_DETAILS = "zones_details"
DEFAULT_PORT = 8080 DEFAULT_PORT = 8080
DEFAULT_SCAN_INTERVAL = timedelta(seconds=60)
DEFAULT_ZONE_RUN = 60 * 10
PROGRAM_UPDATE_TOPIC = f"{DOMAIN}_program_update" PROGRAM_UPDATE_TOPIC = f"{DOMAIN}_program_update"
SENSOR_UPDATE_TOPIC = f"{DOMAIN}_data_update" SENSOR_UPDATE_TOPIC = f"{DOMAIN}_data_update"

View file

@ -4,7 +4,7 @@ from unittest.mock import patch
from regenmaschine.errors import RainMachineError from regenmaschine.errors import RainMachineError
from homeassistant import data_entry_flow from homeassistant import data_entry_flow
from homeassistant.components.rainmachine import DOMAIN, config_flow from homeassistant.components.rainmachine import CONF_ZONE_RUN_TIME, DOMAIN, config_flow
from homeassistant.config_entries import SOURCE_USER from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import ( from homeassistant.const import (
CONF_IP_ADDRESS, CONF_IP_ADDRESS,
@ -98,6 +98,7 @@ async def test_step_import(hass):
CONF_PORT: 8080, CONF_PORT: 8080,
CONF_SSL: True, CONF_SSL: True,
CONF_SCAN_INTERVAL: 60, CONF_SCAN_INTERVAL: 60,
CONF_ZONE_RUN_TIME: 600,
} }
@ -129,4 +130,5 @@ async def test_step_user(hass):
CONF_PORT: 8080, CONF_PORT: 8080,
CONF_SSL: True, CONF_SSL: True,
CONF_SCAN_INTERVAL: 60, CONF_SCAN_INTERVAL: 60,
CONF_ZONE_RUN_TIME: 600,
} }