From 794736b5031785bb0569b9a4fdc98e9e8bc06e3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pedro=20Janu=C3=A1rio?= <prnjanuario@gmail.com>
Date: Fri, 22 Sep 2023 11:20:48 +0100
Subject: [PATCH] Add switch platform to ecoforest integration (#100708)

* add switch platform to ecoforest integration

* ignore switch.py from coverage

* rename mixin

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* update translations

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* remove translation key

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* move attr name to description

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* fix broken change

* use entity description action

* use lambda with awaitable

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
---
 .coveragerc                                   |  1 +
 .../components/ecoforest/__init__.py          |  2 +-
 homeassistant/components/ecoforest/switch.py  | 78 +++++++++++++++++++
 3 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 homeassistant/components/ecoforest/switch.py

diff --git a/.coveragerc b/.coveragerc
index 2eebbee3a3e..da0b312ac83 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -264,6 +264,7 @@ omit =
     homeassistant/components/ecoforest/entity.py
     homeassistant/components/ecoforest/number.py
     homeassistant/components/ecoforest/sensor.py
+    homeassistant/components/ecoforest/switch.py
     homeassistant/components/econet/__init__.py
     homeassistant/components/econet/binary_sensor.py
     homeassistant/components/econet/climate.py
diff --git a/homeassistant/components/ecoforest/__init__.py b/homeassistant/components/ecoforest/__init__.py
index 1e2667256b1..205dfe67deb 100644
--- a/homeassistant/components/ecoforest/__init__.py
+++ b/homeassistant/components/ecoforest/__init__.py
@@ -18,7 +18,7 @@ from homeassistant.exceptions import ConfigEntryNotReady
 from .const import DOMAIN
 from .coordinator import EcoforestCoordinator
 
-PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.NUMBER]
+PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.NUMBER, Platform.SWITCH]
 
 _LOGGER = logging.getLogger(__name__)
 
diff --git a/homeassistant/components/ecoforest/switch.py b/homeassistant/components/ecoforest/switch.py
new file mode 100644
index 00000000000..32341ff5d61
--- /dev/null
+++ b/homeassistant/components/ecoforest/switch.py
@@ -0,0 +1,78 @@
+"""Switch platform for Ecoforest."""
+from __future__ import annotations
+
+from collections.abc import Awaitable, Callable
+from dataclasses import dataclass
+
+from pyecoforest.api import EcoforestApi
+from pyecoforest.models.device import Device
+
+from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
+from homeassistant.config_entries import ConfigEntry
+from homeassistant.core import HomeAssistant
+from homeassistant.helpers.entity_platform import AddEntitiesCallback
+
+from .const import DOMAIN
+from .coordinator import EcoforestCoordinator
+from .entity import EcoforestEntity
+
+
+@dataclass
+class EcoforestSwitchRequiredKeysMixin:
+    """Mixin for required keys."""
+
+    value_fn: Callable[[Device], bool]
+    switch_fn: Callable[[EcoforestApi, bool], Awaitable[Device]]
+
+
+@dataclass
+class EcoforestSwitchEntityDescription(
+    SwitchEntityDescription, EcoforestSwitchRequiredKeysMixin
+):
+    """Describes an Ecoforest switch entity."""
+
+
+SWITCH_TYPES: tuple[EcoforestSwitchEntityDescription, ...] = (
+    EcoforestSwitchEntityDescription(
+        key="status",
+        name=None,
+        value_fn=lambda data: data.on,
+        switch_fn=lambda api, status: api.turn(status),
+    ),
+)
+
+
+async def async_setup_entry(
+    hass: HomeAssistant,
+    config_entry: ConfigEntry,
+    async_add_entities: AddEntitiesCallback,
+) -> None:
+    """Set up Ecoforest switch platform."""
+    coordinator: EcoforestCoordinator = hass.data[DOMAIN][config_entry.entry_id]
+
+    entities = [
+        EcoforestSwitchEntity(coordinator, description) for description in SWITCH_TYPES
+    ]
+
+    async_add_entities(entities)
+
+
+class EcoforestSwitchEntity(EcoforestEntity, SwitchEntity):
+    """Representation of an Ecoforest switch entity."""
+
+    entity_description: EcoforestSwitchEntityDescription
+
+    @property
+    def is_on(self) -> bool:
+        """Return the state of the ecoforest device."""
+        return self.entity_description.value_fn(self.data)
+
+    async def async_turn_on(self):
+        """Turn on the ecoforest device."""
+        await self.entity_description.switch_fn(self.coordinator.api, True)
+        await self.coordinator.async_request_refresh()
+
+    async def async_turn_off(self):
+        """Turn off the ecoforest device."""
+        await self.entity_description.switch_fn(self.coordinator.api, False)
+        await self.coordinator.async_request_refresh()
-- 
GitLab