diff --git a/.coveragerc b/.coveragerc
index 5068574df78c7d862457686b19f29d3ea10cffa4..9d839cdb5f6195af040effda4c4f315c847020a7 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -309,6 +309,9 @@ omit =
     homeassistant/components/epson/media_player.py
     homeassistant/components/epsonworkforce/sensor.py
     homeassistant/components/eq3btsmart/climate.py
+    homeassistant/components/escea/climate.py
+    homeassistant/components/escea/discovery.py
+    homeassistant/components/escea/__init__.py
     homeassistant/components/esphome/__init__.py
     homeassistant/components/esphome/binary_sensor.py
     homeassistant/components/esphome/button.py
diff --git a/CODEOWNERS b/CODEOWNERS
index e10a8a0b26c2ceb9fa2f49279394f6044a707c21..906119e900667a59aaa4790fc8db837f2e85a45d 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -309,6 +309,8 @@ build.json @home-assistant/supervisor
 /tests/components/epson/ @pszafer
 /homeassistant/components/epsonworkforce/ @ThaStealth
 /homeassistant/components/eq3btsmart/ @rytilahti
+/homeassistant/components/escea/ @lazdavila
+/tests/components/escea/ @lazdavila
 /homeassistant/components/esphome/ @OttoWinter @jesserockz
 /tests/components/esphome/ @OttoWinter @jesserockz
 /homeassistant/components/evil_genius_labs/ @balloob
diff --git a/homeassistant/components/escea/__init__.py b/homeassistant/components/escea/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..95e6765fa959a415ea553f42676d2bac1ae02546
--- /dev/null
+++ b/homeassistant/components/escea/__init__.py
@@ -0,0 +1,22 @@
+"""Platform for the Escea fireplace."""
+
+from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
+from homeassistant.config_entries import ConfigEntry
+from homeassistant.core import HomeAssistant
+
+from .discovery import async_start_discovery_service, async_stop_discovery_service
+
+PLATFORMS = [CLIMATE_DOMAIN]
+
+
+async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
+    """Set up from a config entry."""
+    await async_start_discovery_service(hass)
+    hass.config_entries.async_setup_platforms(entry, PLATFORMS)
+    return True
+
+
+async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
+    """Unload the config entry and stop discovery process."""
+    await async_stop_discovery_service(hass)
+    return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
diff --git a/homeassistant/components/escea/climate.py b/homeassistant/components/escea/climate.py
new file mode 100644
index 0000000000000000000000000000000000000000..7bd7d54353cbbc91f17707a668508ab373b4f51e
--- /dev/null
+++ b/homeassistant/components/escea/climate.py
@@ -0,0 +1,221 @@
+"""Support for the Escea Fireplace."""
+from __future__ import annotations
+
+from collections.abc import Coroutine
+import logging
+from typing import Any
+
+from pescea import Controller
+
+from homeassistant.components.climate import ClimateEntity
+from homeassistant.components.climate.const import (
+    FAN_AUTO,
+    FAN_HIGH,
+    FAN_LOW,
+    ClimateEntityFeature,
+    HVACMode,
+)
+from homeassistant.config_entries import ConfigEntry
+from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS
+from homeassistant.core import HomeAssistant, callback
+from homeassistant.helpers.dispatcher import async_dispatcher_connect
+from homeassistant.helpers.entity import DeviceInfo
+from homeassistant.helpers.entity_platform import AddEntitiesCallback
+
+from .const import (
+    DATA_DISCOVERY_SERVICE,
+    DISPATCH_CONTROLLER_DISCONNECTED,
+    DISPATCH_CONTROLLER_DISCOVERED,
+    DISPATCH_CONTROLLER_RECONNECTED,
+    DISPATCH_CONTROLLER_UPDATE,
+    DOMAIN,
+    ESCEA_FIREPLACE,
+    ESCEA_MANUFACTURER,
+    ICON,
+)
+
+_LOGGER = logging.getLogger(__name__)
+
+_ESCEA_FAN_TO_HA = {
+    Controller.Fan.FLAME_EFFECT: FAN_LOW,
+    Controller.Fan.FAN_BOOST: FAN_HIGH,
+    Controller.Fan.AUTO: FAN_AUTO,
+}
+_HA_FAN_TO_ESCEA = {v: k for k, v in _ESCEA_FAN_TO_HA.items()}
+
+
+async def async_setup_entry(
+    hass: HomeAssistant,
+    config_entry: ConfigEntry,
+    async_add_entities: AddEntitiesCallback,
+) -> None:
+    """Initialize an Escea Controller."""
+    discovery_service = hass.data[DATA_DISCOVERY_SERVICE]
+
+    @callback
+    def init_controller(ctrl: Controller) -> None:
+        """Register the controller device."""
+
+        _LOGGER.debug("Controller UID=%s discovered", ctrl.device_uid)
+
+        entity = ControllerEntity(ctrl)
+        async_add_entities([entity])
+
+    # create any components not yet created
+    for controller in discovery_service.controllers.values():
+        init_controller(controller)
+
+    # connect to register any further components
+    config_entry.async_on_unload(
+        async_dispatcher_connect(hass, DISPATCH_CONTROLLER_DISCOVERED, init_controller)
+    )
+
+
+class ControllerEntity(ClimateEntity):
+    """Representation of Escea Controller."""
+
+    _attr_fan_modes = list(_HA_FAN_TO_ESCEA)
+    _attr_has_entity_name = True
+    _attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF]
+    _attr_icon = ICON
+    _attr_precision = PRECISION_WHOLE
+    _attr_should_poll = False
+    _attr_supported_features = (
+        ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.FAN_MODE
+    )
+    _attr_target_temperature_step = PRECISION_WHOLE
+    _attr_temperature_unit = TEMP_CELSIUS
+
+    def __init__(self, controller: Controller) -> None:
+        """Initialise ControllerDevice."""
+        self._controller = controller
+
+        self._attr_min_temp = controller.min_temp
+        self._attr_max_temp = controller.max_temp
+
+        self._attr_unique_id = controller.device_uid
+
+        # temporary assignment to get past mypy checker
+        unique_id: str = controller.device_uid
+
+        self._attr_device_info = DeviceInfo(
+            identifiers={(DOMAIN, unique_id)},
+            manufacturer=ESCEA_MANUFACTURER,
+            name=ESCEA_FIREPLACE,
+        )
+
+        self._attr_available = True
+
+    async def async_added_to_hass(self) -> None:
+        """Call on adding to hass.
+
+        Registers for connect/disconnect/update events
+        """
+
+        @callback
+        def controller_disconnected(ctrl: Controller, ex: Exception) -> None:
+            """Disconnected from controller."""
+            if ctrl is not self._controller:
+                return
+            self.set_available(False, ex)
+
+        self.async_on_remove(
+            async_dispatcher_connect(
+                self.hass, DISPATCH_CONTROLLER_DISCONNECTED, controller_disconnected
+            )
+        )
+
+        @callback
+        def controller_reconnected(ctrl: Controller) -> None:
+            """Reconnected to controller."""
+            if ctrl is not self._controller:
+                return
+            self.set_available(True)
+
+        self.async_on_remove(
+            async_dispatcher_connect(
+                self.hass, DISPATCH_CONTROLLER_RECONNECTED, controller_reconnected
+            )
+        )
+
+        @callback
+        def controller_update(ctrl: Controller) -> None:
+            """Handle controller data updates."""
+            if ctrl is not self._controller:
+                return
+            self.async_write_ha_state()
+
+        self.async_on_remove(
+            async_dispatcher_connect(
+                self.hass, DISPATCH_CONTROLLER_UPDATE, controller_update
+            )
+        )
+
+    @callback
+    def set_available(self, available: bool, ex: Exception = None) -> None:
+        """Set availability for the controller."""
+        if self._attr_available == available:
+            return
+
+        if available:
+            _LOGGER.debug("Reconnected controller %s ", self._controller.device_uid)
+        else:
+            _LOGGER.debug(
+                "Controller %s disconnected due to exception: %s",
+                self._controller.device_uid,
+                ex,
+            )
+
+        self._attr_available = available
+        self.async_write_ha_state()
+
+    @property
+    def hvac_mode(self) -> HVACMode:
+        """Return current operation ie. heat, cool, idle."""
+        return HVACMode.HEAT if self._controller.is_on else HVACMode.OFF
+
+    @property
+    def current_temperature(self) -> float | None:
+        """Return the current temperature."""
+        return self._controller.current_temp
+
+    @property
+    def target_temperature(self) -> float | None:
+        """Return the temperature we try to reach."""
+        return self._controller.desired_temp
+
+    @property
+    def fan_mode(self) -> str | None:
+        """Return the fan setting."""
+        return _ESCEA_FAN_TO_HA[self._controller.fan]
+
+    async def wrap_and_catch(self, coro: Coroutine) -> None:
+        """Catch any connection errors and set unavailable."""
+        try:
+            await coro
+        except ConnectionError as ex:
+            self.set_available(False, ex)
+        else:
+            self.set_available(True)
+
+    async def async_set_temperature(self, **kwargs: Any) -> None:
+        """Set new target temperature."""
+        temp = kwargs.get(ATTR_TEMPERATURE)
+        if temp is not None:
+            await self.wrap_and_catch(self._controller.set_desired_temp(temp))
+
+    async def async_set_fan_mode(self, fan_mode: str) -> None:
+        """Set new target fan mode."""
+        await self.wrap_and_catch(self._controller.set_fan(_HA_FAN_TO_ESCEA[fan_mode]))
+
+    async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
+        """Set new target operation mode."""
+        await self.wrap_and_catch(self._controller.set_on(hvac_mode == HVACMode.HEAT))
+
+    async def async_turn_on(self) -> None:
+        """Turn the entity on."""
+        await self.wrap_and_catch(self._controller.set_on(True))
+
+    async def async_turn_off(self) -> None:
+        """Turn the entity off."""
+        await self.wrap_and_catch(self._controller.set_on(False))
diff --git a/homeassistant/components/escea/config_flow.py b/homeassistant/components/escea/config_flow.py
new file mode 100644
index 0000000000000000000000000000000000000000..5d0dfea1157aeecfded57e933d0502dab34f1df3
--- /dev/null
+++ b/homeassistant/components/escea/config_flow.py
@@ -0,0 +1,52 @@
+"""Config flow for escea."""
+import asyncio
+from contextlib import suppress
+import logging
+
+from async_timeout import timeout
+
+from homeassistant.core import HomeAssistant, callback
+from homeassistant.helpers import config_entry_flow
+from homeassistant.helpers.dispatcher import async_dispatcher_connect
+
+from .const import (
+    DISPATCH_CONTROLLER_DISCOVERED,
+    DOMAIN,
+    ESCEA_FIREPLACE,
+    TIMEOUT_DISCOVERY,
+)
+from .discovery import async_start_discovery_service, async_stop_discovery_service
+
+_LOGGER = logging.getLogger(__name__)
+
+
+async def _async_has_devices(hass: HomeAssistant) -> bool:
+
+    controller_ready = asyncio.Event()
+
+    @callback
+    def dispatch_discovered(_):
+        controller_ready.set()
+
+    remove_handler = async_dispatcher_connect(
+        hass, DISPATCH_CONTROLLER_DISCOVERED, dispatch_discovered
+    )
+
+    discovery_service = await async_start_discovery_service(hass)
+
+    with suppress(asyncio.TimeoutError):
+        async with timeout(TIMEOUT_DISCOVERY):
+            await controller_ready.wait()
+
+    remove_handler()
+
+    if not discovery_service.controllers:
+        await async_stop_discovery_service(hass)
+        _LOGGER.debug("No controllers found")
+        return False
+
+    _LOGGER.debug("Controllers %s", discovery_service.controllers)
+    return True
+
+
+config_entry_flow.register_discovery_flow(DOMAIN, ESCEA_FIREPLACE, _async_has_devices)
diff --git a/homeassistant/components/escea/const.py b/homeassistant/components/escea/const.py
new file mode 100644
index 0000000000000000000000000000000000000000..c35e77e27198812384f0410abf2cc1c83a6acb3e
--- /dev/null
+++ b/homeassistant/components/escea/const.py
@@ -0,0 +1,15 @@
+"""Constants used by the escea component."""
+
+DOMAIN = "escea"
+ESCEA_MANUFACTURER = "Escea"
+ESCEA_FIREPLACE = "Escea Fireplace"
+ICON = "mdi:fire"
+
+DATA_DISCOVERY_SERVICE = "escea_discovery"
+
+DISPATCH_CONTROLLER_DISCOVERED = "escea_controller_discovered"
+DISPATCH_CONTROLLER_DISCONNECTED = "escea_controller_disconnected"
+DISPATCH_CONTROLLER_RECONNECTED = "escea_controller_reconnected"
+DISPATCH_CONTROLLER_UPDATE = "escea_controller_update"
+
+TIMEOUT_DISCOVERY = 20
diff --git a/homeassistant/components/escea/discovery.py b/homeassistant/components/escea/discovery.py
new file mode 100644
index 0000000000000000000000000000000000000000..0d7f3024bfc2254f297d6a73bb4825d583073003
--- /dev/null
+++ b/homeassistant/components/escea/discovery.py
@@ -0,0 +1,75 @@
+"""Internal discovery service for  Escea Fireplace."""
+from __future__ import annotations
+
+from pescea import (
+    AbstractDiscoveryService,
+    Controller,
+    Listener,
+    discovery_service as pescea_discovery_service,
+)
+
+from homeassistant.core import HomeAssistant
+from homeassistant.helpers.dispatcher import async_dispatcher_send
+
+from .const import (
+    DATA_DISCOVERY_SERVICE,
+    DISPATCH_CONTROLLER_DISCONNECTED,
+    DISPATCH_CONTROLLER_DISCOVERED,
+    DISPATCH_CONTROLLER_RECONNECTED,
+    DISPATCH_CONTROLLER_UPDATE,
+)
+
+
+class DiscoveryServiceListener(Listener):
+    """Discovery data and interfacing with pescea library."""
+
+    def __init__(self, hass: HomeAssistant) -> None:
+        """Initialise discovery service."""
+        super().__init__()
+        self.hass = hass
+
+    # Listener interface
+    def controller_discovered(self, ctrl: Controller) -> None:
+        """Handle new controller discoverery."""
+        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_DISCOVERED, ctrl)
+
+    def controller_disconnected(self, ctrl: Controller, ex: Exception) -> None:
+        """On disconnect from controller."""
+        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_DISCONNECTED, ctrl, ex)
+
+    def controller_reconnected(self, ctrl: Controller) -> None:
+        """On reconnect to controller."""
+        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_RECONNECTED, ctrl)
+
+    def controller_update(self, ctrl: Controller) -> None:
+        """System update message is received from the controller."""
+        async_dispatcher_send(self.hass, DISPATCH_CONTROLLER_UPDATE, ctrl)
+
+
+async def async_start_discovery_service(
+    hass: HomeAssistant,
+) -> AbstractDiscoveryService:
+    """Set up the pescea internal discovery."""
+    discovery_service = hass.data.get(DATA_DISCOVERY_SERVICE)
+    if discovery_service:
+        # Already started
+        return discovery_service
+
+    # discovery local services
+    listener = DiscoveryServiceListener(hass)
+    discovery_service = pescea_discovery_service(listener)
+    hass.data[DATA_DISCOVERY_SERVICE] = discovery_service
+
+    await discovery_service.start_discovery()
+
+    return discovery_service
+
+
+async def async_stop_discovery_service(hass: HomeAssistant) -> None:
+    """Stop the discovery service."""
+    discovery_service = hass.data.get(DATA_DISCOVERY_SERVICE)
+    if not discovery_service:
+        return
+
+    await discovery_service.close()
+    del hass.data[DATA_DISCOVERY_SERVICE]
diff --git a/homeassistant/components/escea/manifest.json b/homeassistant/components/escea/manifest.json
new file mode 100644
index 0000000000000000000000000000000000000000..4feb28e982ca948b7c91f20c35bd9fe28ac76b3f
--- /dev/null
+++ b/homeassistant/components/escea/manifest.json
@@ -0,0 +1,12 @@
+{
+  "domain": "escea",
+  "name": "Escea",
+  "documentation": "https://www.home-assistant.io/integrations/escea",
+  "codeowners": ["@lazdavila"],
+  "requirements": ["pescea==1.0.12"],
+  "config_flow": true,
+  "homekit": {
+    "models": ["Escea"]
+  },
+  "iot_class": "local_push"
+}
diff --git a/homeassistant/components/escea/strings.json b/homeassistant/components/escea/strings.json
new file mode 100644
index 0000000000000000000000000000000000000000..8744e74fd3f341282b10ed0d43985a46986feef5
--- /dev/null
+++ b/homeassistant/components/escea/strings.json
@@ -0,0 +1,13 @@
+{
+  "config": {
+    "step": {
+      "confirm": {
+        "description": "Do you want to set up an Escea fireplace?"
+      }
+    },
+    "abort": {
+      "single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]",
+      "no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
+    }
+  }
+}
diff --git a/homeassistant/components/escea/translations/en.json b/homeassistant/components/escea/translations/en.json
new file mode 100644
index 0000000000000000000000000000000000000000..7d4e7b6fa8ba49e01f04d6ccc9fb7507ef6b59fc
--- /dev/null
+++ b/homeassistant/components/escea/translations/en.json
@@ -0,0 +1,13 @@
+{
+    "config": {
+        "abort": {
+            "no_devices_found": "No devices found on the network",
+            "single_instance_allowed": "Already configured. Only a single configuration possible."
+        },
+        "step": {
+            "confirm": {
+                "description": "Do you want to set up an Escea fireplace?"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py
index 327781c25620f3f97ced2b11defcbe521f6f18b2..597cb10fd7f8670cb97a3f57c15d70171337d2ef 100644
--- a/homeassistant/generated/config_flows.py
+++ b/homeassistant/generated/config_flows.py
@@ -99,6 +99,7 @@ FLOWS = {
         "enphase_envoy",
         "environment_canada",
         "epson",
+        "escea",
         "esphome",
         "evil_genius_labs",
         "ezviz",
diff --git a/homeassistant/generated/zeroconf.py b/homeassistant/generated/zeroconf.py
index 5284eef02a7146fab7a2b07f9b26f02bc70eb4a0..d59d37f4579ba1807d53cb474abfb35a09e1923e 100644
--- a/homeassistant/generated/zeroconf.py
+++ b/homeassistant/generated/zeroconf.py
@@ -426,6 +426,7 @@ HOMEKIT = {
     "C105X": "roku",
     "C135X": "roku",
     "EB-*": "ecobee",
+    "Escea": "escea",
     "HHKBridge*": "hive",
     "Healty Home Coach": "netatmo",
     "Iota": "abode",
diff --git a/requirements_all.txt b/requirements_all.txt
index 3a755023ac7ad97e8da3a515fd207e1eb8da48a4..ddf22e985c70944680d84a8080834d4286a88db5 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -1227,6 +1227,9 @@ peco==0.0.29
 # homeassistant.components.pencom
 pencompy==0.0.3
 
+# homeassistant.components.escea
+pescea==1.0.12
+
 # homeassistant.components.aruba
 # homeassistant.components.cisco_ios
 # homeassistant.components.pandora
diff --git a/requirements_test_all.txt b/requirements_test_all.txt
index 7211bb3f08afac3d1961311e1b3608ec999e67a1..a9c556032825d9bbf9ddb8b05fc9cc436403744e 100644
--- a/requirements_test_all.txt
+++ b/requirements_test_all.txt
@@ -854,6 +854,9 @@ pdunehd==1.3.2
 # homeassistant.components.peco
 peco==0.0.29
 
+# homeassistant.components.escea
+pescea==1.0.12
+
 # homeassistant.components.aruba
 # homeassistant.components.cisco_ios
 # homeassistant.components.pandora
diff --git a/tests/components/escea/__init__.py b/tests/components/escea/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b31616f7e584efb62bbf41eb9b14e35aee3e256f
--- /dev/null
+++ b/tests/components/escea/__init__.py
@@ -0,0 +1 @@
+"""Escea tests."""
diff --git a/tests/components/escea/test_config_flow.py b/tests/components/escea/test_config_flow.py
new file mode 100644
index 0000000000000000000000000000000000000000..c4a5b323d221bc5d0890545dd513e80079a25847
--- /dev/null
+++ b/tests/components/escea/test_config_flow.py
@@ -0,0 +1,117 @@
+"""Tests for Escea."""
+
+from collections.abc import Callable, Coroutine
+from unittest.mock import AsyncMock, MagicMock, patch
+
+import pytest
+
+from homeassistant import config_entries, data_entry_flow
+from homeassistant.components.escea.const import DOMAIN, ESCEA_FIREPLACE
+from homeassistant.components.escea.discovery import DiscoveryServiceListener
+from homeassistant.core import HomeAssistant
+
+from tests.common import MockConfigEntry
+
+
+@pytest.fixture(name="mock_discovery_service")
+def mock_discovery_service_fixture() -> AsyncMock:
+    """Mock discovery service."""
+    discovery_service = AsyncMock()
+    discovery_service.controllers = {}
+    return discovery_service
+
+
+@pytest.fixture(name="mock_controller")
+def mock_controller_fixture() -> MagicMock:
+    """Mock controller."""
+    controller = MagicMock()
+    return controller
+
+
+def _mock_start_discovery(
+    discovery_service: MagicMock, controller: MagicMock
+) -> Callable[[], Coroutine[None, None, None]]:
+    """Mock start discovery service."""
+
+    async def do_discovered() -> None:
+        """Call the listener callback."""
+        listener: DiscoveryServiceListener = discovery_service.call_args[0][0]
+        listener.controller_discovered(controller)
+
+    return do_discovered
+
+
+async def test_not_found(
+    hass: HomeAssistant, mock_discovery_service: MagicMock
+) -> None:
+    """Test not finding any Escea controllers."""
+
+    with patch(
+        "homeassistant.components.escea.discovery.pescea_discovery_service"
+    ) as discovery_service, patch(
+        "homeassistant.components.escea.config_flow.TIMEOUT_DISCOVERY", 0
+    ):
+        discovery_service.return_value = mock_discovery_service
+
+        result = await hass.config_entries.flow.async_init(
+            DOMAIN, context={"source": config_entries.SOURCE_USER}
+        )
+
+        # Confirmation form
+        assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
+
+        result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
+        await hass.async_block_till_done()
+
+    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
+    assert result["reason"] == "no_devices_found"
+    assert discovery_service.return_value.close.call_count == 1
+
+
+async def test_found(
+    hass: HomeAssistant, mock_controller: MagicMock, mock_discovery_service: AsyncMock
+) -> None:
+    """Test finding an Escea controller."""
+    mock_discovery_service.controllers["test-uid"] = mock_controller
+
+    with patch(
+        "homeassistant.components.escea.async_setup_entry",
+        return_value=True,
+    ) as mock_setup, patch(
+        "homeassistant.components.escea.discovery.pescea_discovery_service"
+    ) as discovery_service:
+        discovery_service.return_value = mock_discovery_service
+        mock_discovery_service.start_discovery.side_effect = _mock_start_discovery(
+            discovery_service, mock_controller
+        )
+
+        result = await hass.config_entries.flow.async_init(
+            DOMAIN, context={"source": config_entries.SOURCE_USER}
+        )
+
+        # Confirmation form
+        assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
+
+        result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
+        await hass.async_block_till_done()
+
+    assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
+    assert mock_setup.call_count == 1
+
+
+async def test_single_instance_allowed(hass: HomeAssistant) -> None:
+    """Test single instance allowed."""
+    config_entry = MockConfigEntry(domain=DOMAIN, title=ESCEA_FIREPLACE)
+    config_entry.add_to_hass(hass)
+
+    with patch(
+        "homeassistant.components.escea.discovery.pescea_discovery_service"
+    ) as discovery_service:
+        result = await hass.config_entries.flow.async_init(
+            DOMAIN, context={"source": config_entries.SOURCE_USER}
+        )
+        await hass.async_block_till_done()
+
+    assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
+    assert result["reason"] == "single_instance_allowed"
+    assert discovery_service.call_count == 0