Remove yaml import rainbird (#92599)

pull/92629/head
G Johansson 2023-05-05 16:53:40 +02:00 committed by GitHub
parent 835be4758a
commit e41a75f617
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 18 additions and 161 deletions

View File

@ -1,84 +1,21 @@
"""Support for Rain Bird Irrigation system LNK WiFi Module."""
from __future__ import annotations
import logging
from pyrainbird.async_client import AsyncRainbirdClient, AsyncRainbirdController
import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import (
CONF_FRIENDLY_NAME,
CONF_HOST,
CONF_PASSWORD,
CONF_TRIGGER_TIME,
Platform,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType
from .const import CONF_SERIAL_NUMBER, CONF_ZONES
from .const import CONF_SERIAL_NUMBER
from .coordinator import RainbirdUpdateCoordinator
PLATFORMS = [Platform.SWITCH, Platform.SENSOR, Platform.BINARY_SENSOR, Platform.NUMBER]
_LOGGER = logging.getLogger(__name__)
DOMAIN = "rainbird"
TRIGGER_TIME_SCHEMA = vol.All(
cv.time_period, cv.positive_timedelta, lambda td: (td.total_seconds() // 60)
)
ZONE_SCHEMA = vol.Schema(
{
vol.Optional(CONF_FRIENDLY_NAME): cv.string,
vol.Optional(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA,
}
)
CONTROLLER_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_TRIGGER_TIME): TRIGGER_TIME_SCHEMA,
vol.Optional(CONF_ZONES): vol.Schema({cv.positive_int: ZONE_SCHEMA}),
}
)
CONFIG_SCHEMA = vol.Schema(
{DOMAIN: vol.Schema(vol.All(cv.ensure_list, [CONTROLLER_SCHEMA]))},
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Rain Bird component."""
if DOMAIN not in config:
return True
for controller_config in config[DOMAIN]:
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=controller_config,
)
)
async_create_issue(
hass,
DOMAIN,
"deprecated_yaml",
breaks_in_ha_version="2023.4.0",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up the config entry for Rain Bird."""

View File

@ -16,7 +16,7 @@ import voluptuous as vol
from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_FRIENDLY_NAME, CONF_HOST, CONF_PASSWORD
from homeassistant.const import CONF_HOST, CONF_PASSWORD
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import config_validation as cv, selector
@ -24,9 +24,7 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import (
ATTR_DURATION,
CONF_IMPORTED_NAMES,
CONF_SERIAL_NUMBER,
CONF_ZONES,
DEFAULT_TRIGGER_TIME_MINUTES,
DOMAIN,
TIMEOUT_SECONDS,
@ -121,36 +119,6 @@ class RainbirdConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"cannot_connect",
) from err
async def async_step_import(self, config: dict[str, Any]) -> FlowResult:
"""Import a config entry from configuration.yaml."""
self._async_abort_entries_match({CONF_HOST: config[CONF_HOST]})
try:
serial_number = await self._test_connection(
config[CONF_HOST], config[CONF_PASSWORD]
)
except ConfigFlowError as err:
_LOGGER.error("Error during config import: %s", err)
return self.async_abort(reason=err.error_code)
data = {
CONF_HOST: config[CONF_HOST],
CONF_PASSWORD: config[CONF_PASSWORD],
CONF_SERIAL_NUMBER: serial_number,
}
names: dict[str, str] = {}
for zone, zone_config in config.get(CONF_ZONES, {}).items():
if name := zone_config.get(CONF_FRIENDLY_NAME):
names[str(zone)] = name
if names:
data[CONF_IMPORTED_NAMES] = names
return await self.async_finish(
serial_number,
data=data,
options={
ATTR_DURATION: config.get(ATTR_DURATION, DEFAULT_TRIGGER_TIME_MINUTES),
},
)
async def async_finish(
self,
serial_number: str,

View File

@ -4,7 +4,6 @@ DOMAIN = "rainbird"
MANUFACTURER = "Rain Bird"
DEFAULT_TRIGGER_TIME_MINUTES = 6
CONF_ZONES = "zones"
CONF_SERIAL_NUMBER = "serial_number"
CONF_IMPORTED_NAMES = "imported_names"

View File

@ -27,11 +27,5 @@
}
}
}
},
"issues": {
"deprecated_yaml": {
"title": "The Rain Bird YAML configuration is being removed",
"description": "Configuring Rain Bird in configuration.yaml is being removed in Home Assistant 2023.4.\n\nYour configuration has been imported into the UI automatically, however default per-zone irrigation times are no longer supported. Remove the Rain Bird YAML configuration from your configuration.yaml file and restart Home Assistant to fix this issue."
}
}
}

View File

@ -8,14 +8,7 @@ from homeassistant.components.rainbird import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from .conftest import (
CONFIG,
CONFIG_ENTRY_DATA,
SERIAL_RESPONSE,
UNAVAILABLE_RESPONSE,
ComponentSetup,
mock_response,
)
from .conftest import CONFIG_ENTRY_DATA, UNAVAILABLE_RESPONSE, ComponentSetup
from tests.test_util.aiohttp import AiohttpClientMockResponse
@ -24,18 +17,8 @@ from tests.test_util.aiohttp import AiohttpClientMockResponse
("yaml_config", "config_entry_data", "initial_response"),
[
({}, CONFIG_ENTRY_DATA, None),
(
CONFIG,
None,
mock_response(SERIAL_RESPONSE), # Extra import request
),
(
CONFIG,
CONFIG_ENTRY_DATA,
None,
),
],
ids=["config_entry", "yaml", "already_exists"],
ids=["config_entry"],
)
async def test_init_success(
hass: HomeAssistant,
@ -62,25 +45,8 @@ async def test_init_success(
("yaml_config", "config_entry_data", "responses", "config_entry_states"),
[
({}, CONFIG_ENTRY_DATA, [UNAVAILABLE_RESPONSE], [ConfigEntryState.SETUP_RETRY]),
(
CONFIG,
None,
[
UNAVAILABLE_RESPONSE, # Failure when importing yaml
],
[],
),
(
CONFIG,
None,
[
mock_response(SERIAL_RESPONSE), # Import succeeds
UNAVAILABLE_RESPONSE, # Failure on integration setup
],
[ConfigEntryState.SETUP_RETRY],
),
],
ids=["config_entry_failure", "yaml_import_failure", "yaml_init_failure"],
ids=["config_entry_failure"],
)
async def test_communication_failure(
hass: HomeAssistant,

View File

@ -14,7 +14,6 @@ from .conftest import (
PASSWORD,
RAIN_DELAY_OFF,
RAIN_SENSOR_OFF,
SERIAL_RESPONSE,
ZONE_3_ON_RESPONSE,
ZONE_5_ON_RESPONSE,
ZONE_OFF_RESPONSE,
@ -214,32 +213,26 @@ async def test_irrigation_service(
("yaml_config", "config_entry_data"),
[
(
{},
{
DOMAIN: {
"host": HOST,
"password": PASSWORD,
"trigger_time": 360,
"zones": {
1: {
"friendly_name": "Garden Sprinkler",
},
2: {
"friendly_name": "Back Yard",
},
},
}
"host": HOST,
"password": PASSWORD,
"trigger_time": 360,
"serial_number": "0x1263613994342",
"imported_names": {
"1": "Garden Sprinkler",
"2": "Back Yard",
},
},
None,
)
],
)
async def test_yaml_config(
async def test_yaml_imported_config(
hass: HomeAssistant,
setup_integration: ComponentSetup,
responses: list[AiohttpClientMockResponse],
) -> None:
"""Test switch platform with fake data that creates 7 zones with one enabled."""
responses.insert(0, mock_response(SERIAL_RESPONSE)) # Extra import request
"""Test a config entry that was previously imported from yaml."""
assert await setup_integration()
assert hass.states.get("switch.garden_sprinkler")