Remove deprecated YAML configuration from DSMR (#61008)

This commit is contained in:
Franck Nijhof 2021-12-05 17:09:37 +01:00 committed by GitHub
parent f5d7adc018
commit 5efb88f3f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 3 additions and 335 deletions

View File

@ -19,7 +19,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_TYPE from homeassistant.const import CONF_HOST, CONF_PORT, CONF_TYPE
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.typing import ConfigType
from .const import ( from .const import (
CONF_DSMR_VERSION, CONF_DSMR_VERSION,
@ -303,31 +302,6 @@ class DSMRFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
return data return data
async def async_step_import(self, import_config: ConfigType) -> FlowResult:
"""Handle the initial step."""
host = import_config.get(CONF_HOST)
port = import_config[CONF_PORT]
status = self._abort_if_host_port_configured(port, host, import_config)
if status is not None:
return status
try:
info = await _validate_dsmr_connection(self.hass, import_config)
except CannotConnect:
return self.async_abort(reason="cannot_connect")
except CannotCommunicate:
return self.async_abort(reason="cannot_communicate")
name = f"{host}:{port}" if host is not None else port
data = {**import_config, **info}
if info[CONF_SERIAL_ID]:
await self.async_set_unique_id(info[CONF_SERIAL_ID])
self._abort_if_unique_id_configured(data)
return self.async_create_entry(title=name, data=data)
class DSMROptionFlowHandler(config_entries.OptionsFlow): class DSMROptionFlowHandler(config_entries.OptionsFlow):
"""Handle options.""" """Handle options."""

View File

@ -6,16 +6,14 @@ from asyncio import CancelledError
from contextlib import suppress from contextlib import suppress
from datetime import timedelta from datetime import timedelta
from functools import partial from functools import partial
from typing import Any
from dsmr_parser import obis_references as obis_ref from dsmr_parser import obis_references as obis_ref
from dsmr_parser.clients.protocol import create_dsmr_reader, create_tcp_dsmr_reader from dsmr_parser.clients.protocol import create_dsmr_reader, create_tcp_dsmr_reader
from dsmr_parser.objects import DSMRObject from dsmr_parser.objects import DSMRObject
import serial import serial
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity from homeassistant.components.sensor import SensorEntity
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_HOST,
CONF_PORT, CONF_PORT,
@ -23,10 +21,9 @@ from homeassistant.const import (
VOLUME_CUBIC_METERS, VOLUME_CUBIC_METERS,
) )
from homeassistant.core import CoreState, HomeAssistant, callback from homeassistant.core import CoreState, HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, EventType, StateType from homeassistant.helpers.typing import EventType, StateType
from homeassistant.util import Throttle from homeassistant.util import Throttle
from .const import ( from .const import (
@ -37,55 +34,20 @@ from .const import (
CONF_SERIAL_ID_GAS, CONF_SERIAL_ID_GAS,
CONF_TIME_BETWEEN_UPDATE, CONF_TIME_BETWEEN_UPDATE,
DATA_TASK, DATA_TASK,
DEFAULT_DSMR_VERSION,
DEFAULT_PORT,
DEFAULT_PRECISION, DEFAULT_PRECISION,
DEFAULT_RECONNECT_INTERVAL, DEFAULT_RECONNECT_INTERVAL,
DEFAULT_TIME_BETWEEN_UPDATE, DEFAULT_TIME_BETWEEN_UPDATE,
DEVICE_NAME_ENERGY, DEVICE_NAME_ENERGY,
DEVICE_NAME_GAS, DEVICE_NAME_GAS,
DOMAIN, DOMAIN,
DSMR_VERSIONS,
LOGGER, LOGGER,
SENSORS, SENSORS,
) )
from .models import DSMRSensorEntityDescription from .models import DSMRSensorEntityDescription
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.string,
vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_DSMR_VERSION, default=DEFAULT_DSMR_VERSION): vol.All(
cv.string, vol.In(DSMR_VERSIONS)
),
vol.Optional(CONF_RECONNECT_INTERVAL, default=DEFAULT_RECONNECT_INTERVAL): int,
vol.Optional(CONF_PRECISION, default=DEFAULT_PRECISION): vol.Coerce(int),
}
)
UNIT_CONVERSION = {"m3": VOLUME_CUBIC_METERS} UNIT_CONVERSION = {"m3": VOLUME_CUBIC_METERS}
async def async_setup_platform(
hass: HomeAssistant,
config: ConfigType,
async_add_entities: AddEntitiesCallback,
discovery_info: dict[str, Any] | None = None,
) -> None:
"""Import the platform into a config entry."""
LOGGER.warning(
"Configuration of the DSMR platform in YAML is deprecated and will be "
"removed in Home Assistant 2021.9; Your existing configuration "
"has been imported into the UI automatically and can be safely removed "
"from your configuration.yaml file"
)
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
)
)
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:

View File

@ -1,5 +1,4 @@
"""Test the DSMR config flow.""" """Test the DSMR config flow."""
import asyncio
from itertools import chain, repeat from itertools import chain, repeat
import os import os
from unittest.mock import DEFAULT, AsyncMock, MagicMock, patch, sentinel from unittest.mock import DEFAULT, AsyncMock, MagicMock, patch, sentinel
@ -225,188 +224,6 @@ async def test_setup_serial_wrong_telegram(
assert result["errors"] == {"base": "cannot_communicate"} assert result["errors"] == {"base": "cannot_communicate"}
async def test_import_usb(hass, dsmr_connection_send_validate_fixture):
"""Test we can import."""
entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "2.2",
"precision": 4,
"reconnect_interval": 30,
}
with patch("homeassistant.components.dsmr.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=entry_data,
)
assert result["type"] == "create_entry"
assert result["title"] == "/dev/ttyUSB0"
assert result["data"] == {**entry_data, **SERIAL_DATA}
async def test_import_usb_failed_connection(
hass, dsmr_connection_send_validate_fixture
):
"""Test we can import."""
(connection_factory, transport, protocol) = dsmr_connection_send_validate_fixture
entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "2.2",
"precision": 4,
"reconnect_interval": 30,
}
# override the mock to have it fail the first time and succeed after
first_fail_connection_factory = AsyncMock(
return_value=(transport, protocol),
side_effect=chain([serial.serialutil.SerialException], repeat(DEFAULT)),
)
with patch(
"homeassistant.components.dsmr.async_setup_entry", return_value=True
), patch(
"homeassistant.components.dsmr.config_flow.create_dsmr_reader",
first_fail_connection_factory,
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=entry_data,
)
assert result["type"] == "abort"
assert result["reason"] == "cannot_connect"
async def test_import_usb_no_data(hass, dsmr_connection_send_validate_fixture):
"""Test we can import."""
(connection_factory, transport, protocol) = dsmr_connection_send_validate_fixture
entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "2.2",
"precision": 4,
"reconnect_interval": 30,
}
# override the mock to have it fail the first time and succeed after
wait_closed = AsyncMock(
return_value=(transport, protocol),
side_effect=chain([asyncio.TimeoutError], repeat(DEFAULT)),
)
protocol.wait_closed = wait_closed
with patch("homeassistant.components.dsmr.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=entry_data,
)
assert result["type"] == "abort"
assert result["reason"] == "cannot_communicate"
async def test_import_usb_wrong_telegram(hass, dsmr_connection_send_validate_fixture):
"""Test we can import."""
(connection_factory, transport, protocol) = dsmr_connection_send_validate_fixture
entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "2.2",
"precision": 4,
"reconnect_interval": 30,
}
protocol.telegram = {}
with patch("homeassistant.components.dsmr.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=entry_data,
)
assert result["type"] == "abort"
assert result["reason"] == "cannot_communicate"
async def test_import_network(hass, dsmr_connection_send_validate_fixture):
"""Test we can import from network."""
entry_data = {
"host": "localhost",
"port": "1234",
"dsmr_version": "2.2",
"precision": 4,
"reconnect_interval": 30,
}
with patch("homeassistant.components.dsmr.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=entry_data,
)
assert result["type"] == "create_entry"
assert result["title"] == "localhost:1234"
assert result["data"] == {**entry_data, **SERIAL_DATA}
async def test_import_update(hass, dsmr_connection_send_validate_fixture):
"""Test we can import."""
entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "2.2",
"precision": 4,
"reconnect_interval": 30,
}
entry = MockConfigEntry(
domain=DOMAIN,
data=entry_data,
unique_id="/dev/ttyUSB0",
)
entry.add_to_hass(hass)
with patch(
"homeassistant.components.dsmr.async_setup_entry", return_value=True
), patch("homeassistant.components.dsmr.async_unload_entry", return_value=True):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
new_entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "2.2",
"precision": 3,
"reconnect_interval": 30,
}
with patch(
"homeassistant.components.dsmr.async_setup_entry", return_value=True
), patch("homeassistant.components.dsmr.async_unload_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=new_entry_data,
)
await hass.async_block_till_done()
assert result["type"] == "abort"
assert result["reason"] == "already_configured"
assert entry.data["precision"] == 3
async def test_options_flow(hass): async def test_options_flow(hass):
"""Test options flow.""" """Test options flow."""
@ -446,50 +263,6 @@ async def test_options_flow(hass):
assert entry.options == {"time_between_update": 15} assert entry.options == {"time_between_update": 15}
async def test_import_luxembourg(hass, dsmr_connection_send_validate_fixture):
"""Test we can import."""
entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "5L",
"precision": 4,
"reconnect_interval": 30,
}
with patch("homeassistant.components.dsmr.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=entry_data,
)
assert result["type"] == "create_entry"
assert result["title"] == "/dev/ttyUSB0"
assert result["data"] == {**entry_data, **SERIAL_DATA}
async def test_import_sweden(hass, dsmr_connection_send_validate_fixture):
"""Test we can import."""
entry_data = {
"port": "/dev/ttyUSB0",
"dsmr_version": "5S",
"precision": 4,
"reconnect_interval": 30,
}
with patch("homeassistant.components.dsmr.async_setup_entry", return_value=True):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=entry_data,
)
assert result["type"] == "create_entry"
assert result["title"] == "/dev/ttyUSB0"
assert result["data"] == {**entry_data, **SERIAL_DATA_SWEDEN}
def test_get_serial_by_id_no_dir(): def test_get_serial_by_id_no_dir():
"""Test serial by id conversion if there's no /dev/serial/by-id.""" """Test serial by id conversion if there's no /dev/serial/by-id."""
p1 = patch("os.path.isdir", MagicMock(return_value=False)) p1 = patch("os.path.isdir", MagicMock(return_value=False))

View File

@ -12,10 +12,8 @@ from itertools import chain, repeat
from unittest.mock import DEFAULT, MagicMock from unittest.mock import DEFAULT, MagicMock
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components.dsmr.const import DOMAIN
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
ATTR_STATE_CLASS, ATTR_STATE_CLASS,
DOMAIN as SENSOR_DOMAIN,
SensorDeviceClass, SensorDeviceClass,
SensorStateClass, SensorStateClass,
) )
@ -28,49 +26,10 @@ from homeassistant.const import (
VOLUME_CUBIC_METERS, VOLUME_CUBIC_METERS,
) )
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry, patch from tests.common import MockConfigEntry, patch
async def test_setup_platform(hass, dsmr_connection_fixture):
"""Test setup of platform."""
async_add_entities = MagicMock()
entry_data = {
"platform": DOMAIN,
"port": "/dev/ttyUSB0",
"dsmr_version": "2.2",
"precision": 4,
"reconnect_interval": 30,
}
serial_data = {"serial_id": "1234", "serial_id_gas": "5678"}
with patch(
"homeassistant.components.dsmr.async_setup_entry", return_value=True
), patch(
"homeassistant.components.dsmr.config_flow._validate_dsmr_connection",
return_value=serial_data,
):
assert await async_setup_component(
hass, SENSOR_DOMAIN, {SENSOR_DOMAIN: entry_data}
)
await hass.async_block_till_done()
assert not async_add_entities.called
# Check config entry
conf_entries = hass.config_entries.async_entries(DOMAIN)
assert len(conf_entries) == 1
entry = conf_entries[0]
assert entry.state == config_entries.ConfigEntryState.LOADED
assert entry.data == {**entry_data, **serial_data}
async def test_default_setup(hass, dsmr_connection_fixture): async def test_default_setup(hass, dsmr_connection_fixture):
"""Test the default setup.""" """Test the default setup."""
(connection_factory, transport, protocol) = dsmr_connection_fixture (connection_factory, transport, protocol) = dsmr_connection_fixture