Remove yaml import rainbird (#92599)
This commit is contained in:
parent
835be4758a
commit
e41a75f617
6 changed files with 18 additions and 161 deletions
|
@ -1,84 +1,21 @@
|
||||||
"""Support for Rain Bird Irrigation system LNK WiFi Module."""
|
"""Support for Rain Bird Irrigation system LNK WiFi Module."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
from pyrainbird.async_client import AsyncRainbirdClient, AsyncRainbirdController
|
from pyrainbird.async_client import AsyncRainbirdClient, AsyncRainbirdController
|
||||||
import voluptuous as vol
|
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, Platform
|
||||||
CONF_FRIENDLY_NAME,
|
|
||||||
CONF_HOST,
|
|
||||||
CONF_PASSWORD,
|
|
||||||
CONF_TRIGGER_TIME,
|
|
||||||
Platform,
|
|
||||||
)
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
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
|
from .coordinator import RainbirdUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.SWITCH, Platform.SENSOR, Platform.BINARY_SENSOR, Platform.NUMBER]
|
PLATFORMS = [Platform.SWITCH, Platform.SENSOR, Platform.BINARY_SENSOR, Platform.NUMBER]
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
DOMAIN = "rainbird"
|
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:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up the config entry for Rain Bird."""
|
"""Set up the config entry for Rain Bird."""
|
||||||
|
|
|
@ -16,7 +16,7 @@ import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.config_entries import ConfigEntry
|
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.core import callback
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
from homeassistant.helpers import config_validation as cv, selector
|
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 (
|
from .const import (
|
||||||
ATTR_DURATION,
|
ATTR_DURATION,
|
||||||
CONF_IMPORTED_NAMES,
|
|
||||||
CONF_SERIAL_NUMBER,
|
CONF_SERIAL_NUMBER,
|
||||||
CONF_ZONES,
|
|
||||||
DEFAULT_TRIGGER_TIME_MINUTES,
|
DEFAULT_TRIGGER_TIME_MINUTES,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
TIMEOUT_SECONDS,
|
TIMEOUT_SECONDS,
|
||||||
|
@ -121,36 +119,6 @@ class RainbirdConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
"cannot_connect",
|
"cannot_connect",
|
||||||
) from err
|
) 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(
|
async def async_finish(
|
||||||
self,
|
self,
|
||||||
serial_number: str,
|
serial_number: str,
|
||||||
|
|
|
@ -4,7 +4,6 @@ DOMAIN = "rainbird"
|
||||||
MANUFACTURER = "Rain Bird"
|
MANUFACTURER = "Rain Bird"
|
||||||
DEFAULT_TRIGGER_TIME_MINUTES = 6
|
DEFAULT_TRIGGER_TIME_MINUTES = 6
|
||||||
|
|
||||||
CONF_ZONES = "zones"
|
|
||||||
CONF_SERIAL_NUMBER = "serial_number"
|
CONF_SERIAL_NUMBER = "serial_number"
|
||||||
CONF_IMPORTED_NAMES = "imported_names"
|
CONF_IMPORTED_NAMES = "imported_names"
|
||||||
|
|
||||||
|
|
|
@ -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."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,7 @@ from homeassistant.components.rainbird import DOMAIN
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .conftest import (
|
from .conftest import CONFIG_ENTRY_DATA, UNAVAILABLE_RESPONSE, ComponentSetup
|
||||||
CONFIG,
|
|
||||||
CONFIG_ENTRY_DATA,
|
|
||||||
SERIAL_RESPONSE,
|
|
||||||
UNAVAILABLE_RESPONSE,
|
|
||||||
ComponentSetup,
|
|
||||||
mock_response,
|
|
||||||
)
|
|
||||||
|
|
||||||
from tests.test_util.aiohttp import AiohttpClientMockResponse
|
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"),
|
("yaml_config", "config_entry_data", "initial_response"),
|
||||||
[
|
[
|
||||||
({}, CONFIG_ENTRY_DATA, None),
|
({}, 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(
|
async def test_init_success(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
@ -62,25 +45,8 @@ async def test_init_success(
|
||||||
("yaml_config", "config_entry_data", "responses", "config_entry_states"),
|
("yaml_config", "config_entry_data", "responses", "config_entry_states"),
|
||||||
[
|
[
|
||||||
({}, CONFIG_ENTRY_DATA, [UNAVAILABLE_RESPONSE], [ConfigEntryState.SETUP_RETRY]),
|
({}, 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(
|
async def test_communication_failure(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
|
|
@ -14,7 +14,6 @@ from .conftest import (
|
||||||
PASSWORD,
|
PASSWORD,
|
||||||
RAIN_DELAY_OFF,
|
RAIN_DELAY_OFF,
|
||||||
RAIN_SENSOR_OFF,
|
RAIN_SENSOR_OFF,
|
||||||
SERIAL_RESPONSE,
|
|
||||||
ZONE_3_ON_RESPONSE,
|
ZONE_3_ON_RESPONSE,
|
||||||
ZONE_5_ON_RESPONSE,
|
ZONE_5_ON_RESPONSE,
|
||||||
ZONE_OFF_RESPONSE,
|
ZONE_OFF_RESPONSE,
|
||||||
|
@ -214,32 +213,26 @@ async def test_irrigation_service(
|
||||||
("yaml_config", "config_entry_data"),
|
("yaml_config", "config_entry_data"),
|
||||||
[
|
[
|
||||||
(
|
(
|
||||||
|
{},
|
||||||
{
|
{
|
||||||
DOMAIN: {
|
"host": HOST,
|
||||||
"host": HOST,
|
"password": PASSWORD,
|
||||||
"password": PASSWORD,
|
"trigger_time": 360,
|
||||||
"trigger_time": 360,
|
"serial_number": "0x1263613994342",
|
||||||
"zones": {
|
"imported_names": {
|
||||||
1: {
|
"1": "Garden Sprinkler",
|
||||||
"friendly_name": "Garden Sprinkler",
|
"2": "Back Yard",
|
||||||
},
|
},
|
||||||
2: {
|
|
||||||
"friendly_name": "Back Yard",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
None,
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_yaml_config(
|
async def test_yaml_imported_config(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
setup_integration: ComponentSetup,
|
setup_integration: ComponentSetup,
|
||||||
responses: list[AiohttpClientMockResponse],
|
responses: list[AiohttpClientMockResponse],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test switch platform with fake data that creates 7 zones with one enabled."""
|
"""Test a config entry that was previously imported from yaml."""
|
||||||
responses.insert(0, mock_response(SERIAL_RESPONSE)) # Extra import request
|
|
||||||
assert await setup_integration()
|
assert await setup_integration()
|
||||||
|
|
||||||
assert hass.states.get("switch.garden_sprinkler")
|
assert hass.states.get("switch.garden_sprinkler")
|
||||||
|
|
Loading…
Add table
Reference in a new issue