Remove deprecated YAML import from traccar (#125763)

pull/126535/head
Jan-Philipp Benecke 2024-09-23 19:14:55 +02:00 committed by GitHub
parent 4a424a6603
commit 28c2df37ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 4 additions and 296 deletions

View File

@ -4,50 +4,15 @@ from __future__ import annotations
from datetime import timedelta
import logging
from typing import Any
from pytraccar import ApiClient, TraccarException
import voluptuous as vol
from homeassistant.components.device_tracker import (
PLATFORM_SCHEMA as DEVICE_TRACKER_PLATFORM_SCHEMA,
AsyncSeeCallback,
SourceType,
TrackerEntity,
)
from homeassistant.components.device_tracker.legacy import (
YAML_DEVICES,
remove_device_from_config,
)
from homeassistant.config import load_yaml_config_file
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import (
CONF_EVENT,
CONF_HOST,
CONF_MONITORED_CONDITIONS,
CONF_PASSWORD,
CONF_PORT,
CONF_SSL,
CONF_USERNAME,
CONF_VERIFY_SSL,
EVENT_HOMEASSISTANT_STARTED,
)
from homeassistant.core import (
DOMAIN as HOMEASSISTANT_DOMAIN,
Event,
HomeAssistant,
callback,
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.components.device_tracker import SourceType, TrackerEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import slugify
from . import DOMAIN, TRACKER_UPDATE
from .const import (
@ -58,8 +23,6 @@ from .const import (
ATTR_LATITUDE,
ATTR_LONGITUDE,
ATTR_SPEED,
CONF_MAX_ACCURACY,
CONF_SKIP_ACCURACY_ON,
EVENT_ALARM,
EVENT_ALL_EVENTS,
EVENT_COMMAND_RESULT,
@ -104,28 +67,6 @@ EVENTS = [
EVENT_ALL_EVENTS,
]
PLATFORM_SCHEMA = DEVICE_TRACKER_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_PASSWORD): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_HOST): cv.string,
vol.Optional(CONF_PORT, default=8082): cv.port,
vol.Optional(CONF_SSL, default=False): cv.boolean,
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
vol.Required(CONF_MAX_ACCURACY, default=0): cv.positive_int,
vol.Optional(CONF_SKIP_ACCURACY_ON, default=[]): vol.All(
cv.ensure_list, [cv.string]
),
vol.Optional(CONF_MONITORED_CONDITIONS, default=[]): vol.All(
cv.ensure_list, [cv.string]
),
vol.Optional(CONF_EVENT, default=[]): vol.All(
cv.ensure_list,
[vol.In(EVENTS)],
),
}
)
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
@ -167,80 +108,6 @@ async def async_setup_entry(
async_add_entities(entities)
async def async_setup_scanner(
hass: HomeAssistant,
config: ConfigType,
async_see: AsyncSeeCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> bool:
"""Import configuration to the new integration."""
api = ApiClient(
host=config[CONF_HOST],
port=config[CONF_PORT],
ssl=config[CONF_SSL],
username=config[CONF_USERNAME],
password=config[CONF_PASSWORD],
client_session=async_get_clientsession(hass, config[CONF_VERIFY_SSL]),
)
async def _run_import(_: Event):
known_devices: dict[str, dict[str, Any]] = {}
try:
known_devices = await hass.async_add_executor_job(
load_yaml_config_file, hass.config.path(YAML_DEVICES)
)
except (FileNotFoundError, HomeAssistantError):
_LOGGER.debug(
"No valid known_devices.yaml found, "
"skip removal of devices from known_devices.yaml"
)
if known_devices:
traccar_devices: list[str] = []
try:
resp = await api.get_devices()
traccar_devices = [slugify(device["name"]) for device in resp]
except TraccarException as exception:
_LOGGER.error("Error while getting device data: %s", exception)
return
for dev_name in traccar_devices:
if dev_name in known_devices:
await hass.async_add_executor_job(
remove_device_from_config, hass, dev_name
)
_LOGGER.debug("Removed device %s from known_devices.yaml", dev_name)
if not hass.states.async_available(f"device_tracker.{dev_name}"):
hass.states.async_remove(f"device_tracker.{dev_name}")
hass.async_create_task(
hass.config_entries.flow.async_init(
"traccar_server",
context={"source": SOURCE_IMPORT},
data=config,
)
)
async_create_issue(
hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{DOMAIN}",
breaks_in_ha_version="2024.8.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Traccar",
},
)
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, _run_import)
return True
class TraccarEntity(TrackerEntity, RestoreEntity):
"""Represent a tracked device."""

View File

@ -160,39 +160,6 @@ class TraccarServerConfigFlow(ConfigFlow, domain=DOMAIN):
errors=errors,
)
async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Import an entry."""
configured_port = str(import_data[CONF_PORT])
self._async_abort_entries_match(
{
CONF_HOST: import_data[CONF_HOST],
CONF_PORT: configured_port,
}
)
if "all_events" in (imported_events := import_data.get("event", [])):
events = list(EVENTS.values())
else:
events = imported_events
return self.async_create_entry(
title=f"{import_data[CONF_HOST]}:{configured_port}",
data={
CONF_HOST: import_data[CONF_HOST],
CONF_PORT: configured_port,
CONF_SSL: import_data.get(CONF_SSL, False),
CONF_VERIFY_SSL: import_data.get(CONF_VERIFY_SSL, True),
CONF_USERNAME: import_data[CONF_USERNAME],
CONF_PASSWORD: import_data[CONF_PASSWORD],
},
options={
CONF_MAX_ACCURACY: import_data[CONF_MAX_ACCURACY],
CONF_EVENTS: events,
CONF_CUSTOM_ATTRIBUTES: import_data.get("monitored_conditions", []),
CONF_SKIP_ACCURACY_FILTER_FOR: import_data.get(
"skip_accuracy_filter_on", []
),
},
)
@staticmethod
@callback
def async_get_options_flow(

View File

@ -1,23 +1,18 @@
"""Test the Traccar Server config flow."""
from collections.abc import Generator
from typing import Any
from unittest.mock import AsyncMock
import pytest
from pytraccar import TraccarException
from homeassistant import config_entries
# pylint: disable-next=hass-component-root-import
from homeassistant.components.traccar.device_tracker import PLATFORM_SCHEMA
from homeassistant.components.traccar_server.const import (
CONF_CUSTOM_ATTRIBUTES,
CONF_EVENTS,
CONF_MAX_ACCURACY,
CONF_SKIP_ACCURACY_FILTER_FOR,
DOMAIN,
EVENTS,
)
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import (
@ -155,127 +150,6 @@ async def test_options(
}
@pytest.mark.parametrize(
("imported", "data", "options"),
[
(
{
CONF_HOST: "1.1.1.1",
CONF_PORT: 443,
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
},
{
CONF_HOST: "1.1.1.1",
CONF_PORT: "443",
CONF_VERIFY_SSL: True,
CONF_SSL: False,
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
},
{
CONF_EVENTS: [],
CONF_CUSTOM_ATTRIBUTES: [],
CONF_SKIP_ACCURACY_FILTER_FOR: [],
CONF_MAX_ACCURACY: 0,
},
),
(
{
CONF_HOST: "1.1.1.1",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
CONF_SSL: True,
"event": ["device_online", "device_offline"],
},
{
CONF_HOST: "1.1.1.1",
CONF_PORT: "8082",
CONF_VERIFY_SSL: True,
CONF_SSL: True,
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
},
{
CONF_EVENTS: ["device_online", "device_offline"],
CONF_CUSTOM_ATTRIBUTES: [],
CONF_SKIP_ACCURACY_FILTER_FOR: [],
CONF_MAX_ACCURACY: 0,
},
),
(
{
CONF_HOST: "1.1.1.1",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
CONF_SSL: True,
"event": ["device_online", "device_offline", "all_events"],
},
{
CONF_HOST: "1.1.1.1",
CONF_PORT: "8082",
CONF_VERIFY_SSL: True,
CONF_SSL: True,
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
},
{
CONF_EVENTS: list(EVENTS.values()),
CONF_CUSTOM_ATTRIBUTES: [],
CONF_SKIP_ACCURACY_FILTER_FOR: [],
CONF_MAX_ACCURACY: 0,
},
),
],
)
async def test_import_from_yaml(
hass: HomeAssistant,
imported: dict[str, Any],
data: dict[str, Any],
options: dict[str, Any],
mock_traccar_api_client: Generator[AsyncMock],
) -> None:
"""Test importing configuration from YAML."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=PLATFORM_SCHEMA({"platform": "traccar", **imported}),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == f"{data[CONF_HOST]}:{data[CONF_PORT]}"
assert result["data"] == data
assert result["options"] == options
assert result["result"].state is ConfigEntryState.LOADED
async def test_abort_import_already_configured(hass: HomeAssistant) -> None:
"""Test abort for existing server while importing."""
config_entry = MockConfigEntry(
domain=DOMAIN,
data={CONF_HOST: "1.1.1.1", CONF_PORT: "8082"},
)
config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=PLATFORM_SCHEMA(
{
"platform": "traccar",
CONF_USERNAME: "test-username",
CONF_PASSWORD: "test-password",
CONF_HOST: "1.1.1.1",
CONF_PORT: "8082",
}
),
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_abort_already_configured(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,