Remove deprecated YAML configuration from DSMR (#61008)
parent
f5d7adc018
commit
5efb88f3f1
homeassistant/components/dsmr
tests/components/dsmr
|
@ -19,7 +19,6 @@ from homeassistant.config_entries import ConfigEntry
|
|||
from homeassistant.const import CONF_HOST, CONF_PORT, CONF_TYPE
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from .const import (
|
||||
CONF_DSMR_VERSION,
|
||||
|
@ -303,31 +302,6 @@ class DSMRFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
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):
|
||||
"""Handle options."""
|
||||
|
|
|
@ -6,16 +6,14 @@ from asyncio import CancelledError
|
|||
from contextlib import suppress
|
||||
from datetime import timedelta
|
||||
from functools import partial
|
||||
from typing import Any
|
||||
|
||||
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.objects import DSMRObject
|
||||
import serial
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
|
@ -23,10 +21,9 @@ from homeassistant.const import (
|
|||
VOLUME_CUBIC_METERS,
|
||||
)
|
||||
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_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, EventType, StateType
|
||||
from homeassistant.helpers.typing import EventType, StateType
|
||||
from homeassistant.util import Throttle
|
||||
|
||||
from .const import (
|
||||
|
@ -37,55 +34,20 @@ from .const import (
|
|||
CONF_SERIAL_ID_GAS,
|
||||
CONF_TIME_BETWEEN_UPDATE,
|
||||
DATA_TASK,
|
||||
DEFAULT_DSMR_VERSION,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_PRECISION,
|
||||
DEFAULT_RECONNECT_INTERVAL,
|
||||
DEFAULT_TIME_BETWEEN_UPDATE,
|
||||
DEVICE_NAME_ENERGY,
|
||||
DEVICE_NAME_GAS,
|
||||
DOMAIN,
|
||||
DSMR_VERSIONS,
|
||||
LOGGER,
|
||||
SENSORS,
|
||||
)
|
||||
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}
|
||||
|
||||
|
||||
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(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""Test the DSMR config flow."""
|
||||
import asyncio
|
||||
from itertools import chain, repeat
|
||||
import os
|
||||
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"}
|
||||
|
||||
|
||||
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):
|
||||
"""Test options flow."""
|
||||
|
||||
|
@ -446,50 +263,6 @@ async def test_options_flow(hass):
|
|||
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():
|
||||
"""Test serial by id conversion if there's no /dev/serial/by-id."""
|
||||
p1 = patch("os.path.isdir", MagicMock(return_value=False))
|
||||
|
|
|
@ -12,10 +12,8 @@ from itertools import chain, repeat
|
|||
from unittest.mock import DEFAULT, MagicMock
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.dsmr.const import DOMAIN
|
||||
from homeassistant.components.sensor import (
|
||||
ATTR_STATE_CLASS,
|
||||
DOMAIN as SENSOR_DOMAIN,
|
||||
SensorDeviceClass,
|
||||
SensorStateClass,
|
||||
)
|
||||
|
@ -28,49 +26,10 @@ from homeassistant.const import (
|
|||
VOLUME_CUBIC_METERS,
|
||||
)
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
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):
|
||||
"""Test the default setup."""
|
||||
(connection_factory, transport, protocol) = dsmr_connection_fixture
|
||||
|
|
Loading…
Reference in New Issue