Add port to config flow of P1 Monitor integration (#128324)
parent
5497697cf2
commit
a0637a6ff8
|
@ -3,11 +3,11 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import DOMAIN, LOGGER
|
||||
from .coordinator import P1MonitorDataUpdateCoordinator
|
||||
|
||||
PLATFORMS = [Platform.SENSOR]
|
||||
|
@ -30,6 +30,29 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
return True
|
||||
|
||||
|
||||
async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
|
||||
"""Migrate old entry."""
|
||||
LOGGER.debug("Migrating from version %s", config_entry.version)
|
||||
|
||||
if config_entry.version == 1:
|
||||
# Migrate to split host and port
|
||||
host = config_entry.data[CONF_HOST]
|
||||
if ":" in host:
|
||||
host, port = host.split(":")
|
||||
else:
|
||||
port = 80
|
||||
|
||||
new_data = {
|
||||
**config_entry.data,
|
||||
CONF_HOST: host,
|
||||
CONF_PORT: int(port),
|
||||
}
|
||||
|
||||
hass.config_entries.async_update_entry(config_entry, data=new_data, version=2)
|
||||
LOGGER.debug("Migration to version %s successful", config_entry.version)
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Unload P1 Monitor config entry."""
|
||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
|
|
@ -8,7 +8,7 @@ from p1monitor import P1Monitor, P1MonitorError
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.selector import TextSelector
|
||||
|
||||
|
@ -18,7 +18,7 @@ from .const import DOMAIN
|
|||
class P1MonitorFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
"""Config flow for P1 Monitor."""
|
||||
|
||||
VERSION = 1
|
||||
VERSION = 2
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
|
@ -31,7 +31,9 @@ class P1MonitorFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
session = async_get_clientsession(self.hass)
|
||||
try:
|
||||
async with P1Monitor(
|
||||
host=user_input[CONF_HOST], session=session
|
||||
host=user_input[CONF_HOST],
|
||||
port=user_input[CONF_PORT],
|
||||
session=session,
|
||||
) as client:
|
||||
await client.smartmeter()
|
||||
except P1MonitorError:
|
||||
|
@ -41,6 +43,7 @@ class P1MonitorFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
title="P1 Monitor",
|
||||
data={
|
||||
CONF_HOST: user_input[CONF_HOST],
|
||||
CONF_PORT: user_input[CONF_PORT],
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -49,6 +52,7 @@ class P1MonitorFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_HOST): TextSelector(),
|
||||
vol.Required(CONF_PORT, default=80): int,
|
||||
}
|
||||
),
|
||||
errors=errors,
|
||||
|
|
|
@ -15,7 +15,7 @@ from p1monitor import (
|
|||
)
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
@ -59,7 +59,9 @@ class P1MonitorDataUpdateCoordinator(DataUpdateCoordinator[P1MonitorData]):
|
|||
)
|
||||
|
||||
self.p1monitor = P1Monitor(
|
||||
self.config_entry.data[CONF_HOST], session=async_get_clientsession(hass)
|
||||
host=self.config_entry.data[CONF_HOST],
|
||||
port=self.config_entry.data[CONF_PORT],
|
||||
session=async_get_clientsession(hass),
|
||||
)
|
||||
|
||||
async def _async_update_data(self) -> P1MonitorData:
|
||||
|
|
|
@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any, cast
|
|||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .const import (
|
||||
|
@ -22,9 +22,7 @@ from .coordinator import P1MonitorDataUpdateCoordinator
|
|||
if TYPE_CHECKING:
|
||||
from _typeshed import DataclassInstance
|
||||
|
||||
TO_REDACT = {
|
||||
CONF_HOST,
|
||||
}
|
||||
TO_REDACT = {CONF_HOST, CONF_PORT}
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
"user": {
|
||||
"description": "Set up P1 Monitor to integrate with Home Assistant.",
|
||||
"data": {
|
||||
"host": "[%key:common::config_flow::data::host%]"
|
||||
"host": "[%key:common::config_flow::data::host%]",
|
||||
"port": "[%key:common::config_flow::data::port%]"
|
||||
},
|
||||
"data_description": {
|
||||
"host": "The IP address or hostname of your P1 Monitor installation."
|
||||
"host": "The IP address or hostname of your P1 Monitor installation.",
|
||||
"port": "The port of your P1 Monitor installation."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ from p1monitor import Phases, Settings, SmartMeter, WaterMeter
|
|||
import pytest
|
||||
|
||||
from homeassistant.components.p1_monitor.const import DOMAIN
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry, load_fixture
|
||||
|
@ -19,8 +19,9 @@ def mock_config_entry() -> MockConfigEntry:
|
|||
return MockConfigEntry(
|
||||
title="monitor",
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "example"},
|
||||
data={CONF_HOST: "example", CONF_PORT: 80},
|
||||
unique_id="unique_thingy",
|
||||
version=2,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# serializer version: 1
|
||||
# name: test_migration
|
||||
ConfigEntrySnapshot({
|
||||
'data': dict({
|
||||
'host': 'example',
|
||||
'port': 80,
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'discovery_keys': dict({
|
||||
}),
|
||||
'domain': 'p1_monitor',
|
||||
'entry_id': <ANY>,
|
||||
'minor_version': 1,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'title': 'Mock Title',
|
||||
'unique_id': 'unique_thingy',
|
||||
'version': 2,
|
||||
})
|
||||
# ---
|
||||
# name: test_port_migration
|
||||
ConfigEntrySnapshot({
|
||||
'data': dict({
|
||||
'host': 'example',
|
||||
'port': 80,
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'discovery_keys': dict({
|
||||
}),
|
||||
'domain': 'p1_monitor',
|
||||
'entry_id': <ANY>,
|
||||
'minor_version': 1,
|
||||
'options': dict({
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'title': 'Mock Title',
|
||||
'unique_id': 'unique_thingy',
|
||||
'version': 2,
|
||||
})
|
||||
# ---
|
|
@ -6,7 +6,7 @@ from p1monitor import P1MonitorError
|
|||
|
||||
from homeassistant.components.p1_monitor.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
|
@ -30,12 +30,12 @@ async def test_full_user_flow(hass: HomeAssistant) -> None:
|
|||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={CONF_HOST: "example.com"},
|
||||
user_input={CONF_HOST: "example.com", CONF_PORT: 80},
|
||||
)
|
||||
|
||||
assert result2.get("type") is FlowResultType.CREATE_ENTRY
|
||||
assert result2.get("title") == "P1 Monitor"
|
||||
assert result2.get("data") == {CONF_HOST: "example.com"}
|
||||
assert result2.get("data") == {CONF_HOST: "example.com", CONF_PORT: 80}
|
||||
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert len(mock_p1monitor.mock_calls) == 1
|
||||
|
@ -50,7 +50,7 @@ async def test_api_error(hass: HomeAssistant) -> None:
|
|||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_USER},
|
||||
data={CONF_HOST: "example.com"},
|
||||
data={CONF_HOST: "example.com", CONF_PORT: 80},
|
||||
)
|
||||
|
||||
assert result.get("type") is FlowResultType.FORM
|
||||
|
|
|
@ -21,6 +21,7 @@ async def test_diagnostics(
|
|||
"title": "monitor",
|
||||
"data": {
|
||||
"host": REDACTED,
|
||||
"port": REDACTED,
|
||||
},
|
||||
},
|
||||
"data": {
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
from p1monitor import P1MonitorConnectionError
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.p1_monitor.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_HOST
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
@ -44,3 +46,35 @@ async def test_config_entry_not_ready(
|
|||
|
||||
assert mock_request.call_count == 1
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_migration(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
"""Test config entry version 1 -> 2 migration."""
|
||||
mock_config_entry = MockConfigEntry(
|
||||
unique_id="unique_thingy",
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "example"},
|
||||
version=1,
|
||||
)
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.config_entries.async_get_entry(mock_config_entry.entry_id) == snapshot
|
||||
|
||||
|
||||
async def test_port_migration(hass: HomeAssistant, snapshot: SnapshotAssertion) -> None:
|
||||
"""Test migration of host:port to separate host and port."""
|
||||
mock_config_entry = MockConfigEntry(
|
||||
unique_id="unique_thingy",
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: "example:80"},
|
||||
version=1,
|
||||
)
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.config_entries.async_get_entry(mock_config_entry.entry_id) == snapshot
|
||||
|
|
Loading…
Reference in New Issue