From e6c94d78548625f3148af10877b824924e7cbb45 Mon Sep 17 00:00:00 2001
From: Martin Hjelmare <marhje52@gmail.com>
Date: Tue, 28 Mar 2023 13:05:09 +0200
Subject: [PATCH] Remove mysensors notify (#90402)

---
 .../components/mysensors/__init__.py          |  51 ++-------
 homeassistant/components/mysensors/const.py   |   8 +-
 homeassistant/components/mysensors/notify.py  | 100 ------------------
 .../components/mysensors/test_config_flow.py  |  15 ---
 tests/components/mysensors/test_notify.py     |  95 -----------------
 5 files changed, 8 insertions(+), 261 deletions(-)
 delete mode 100644 homeassistant/components/mysensors/notify.py
 delete mode 100644 tests/components/mysensors/test_notify.py

diff --git a/homeassistant/components/mysensors/__init__.py b/homeassistant/components/mysensors/__init__.py
index d8c3debe7ed..129b1430625 100644
--- a/homeassistant/components/mysensors/__init__.py
+++ b/homeassistant/components/mysensors/__init__.py
@@ -2,7 +2,6 @@
 from __future__ import annotations
 
 from collections.abc import Callable
-from functools import partial
 import logging
 
 from mysensors import BaseAsyncGateway
@@ -12,24 +11,19 @@ from homeassistant.const import Platform
 from homeassistant.core import HomeAssistant, callback
 import homeassistant.helpers.config_validation as cv
 from homeassistant.helpers.device_registry import DeviceEntry
-from homeassistant.helpers.discovery import async_load_platform
-from homeassistant.helpers.dispatcher import async_dispatcher_connect
-from homeassistant.helpers.typing import ConfigType
 
 from .const import (
     ATTR_DEVICES,
     DOMAIN,
-    MYSENSORS_DISCOVERY,
     MYSENSORS_GATEWAYS,
     MYSENSORS_ON_UNLOAD,
-    PLATFORMS_WITH_ENTRY_SUPPORT,
+    PLATFORMS,
     DevId,
     DiscoveryInfo,
     SensorType,
 )
 from .device import MySensorsDevice, get_mysensors_devices
 from .gateway import finish_setup, gw_stop, setup_gateway
-from .helpers import on_unload
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -39,14 +33,6 @@ DATA_HASS_CONFIG = "hass_config"
 CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
 
 
-async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
-    """Set up the MySensors component."""
-    # This is needed to set up the notify platform via discovery.
-    hass.data[DOMAIN] = {DATA_HASS_CONFIG: config}
-
-    return True
-
-
 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
     """Set up an instance of the MySensors integration.
 
@@ -58,33 +44,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
         _LOGGER.error("Gateway setup failed for %s", entry.data)
         return False
 
-    if MYSENSORS_GATEWAYS not in hass.data[DOMAIN]:
-        hass.data[DOMAIN][MYSENSORS_GATEWAYS] = {}
-    hass.data[DOMAIN][MYSENSORS_GATEWAYS][entry.entry_id] = gateway
-
-    # Connect notify discovery as that integration doesn't support entry forwarding.
+    mysensors_data = hass.data.setdefault(DOMAIN, {})
+    if MYSENSORS_GATEWAYS not in mysensors_data:
+        mysensors_data[MYSENSORS_GATEWAYS] = {}
+    mysensors_data[MYSENSORS_GATEWAYS][entry.entry_id] = gateway
 
-    load_discovery_platform = partial(
-        async_load_platform,
-        hass,
-        Platform.NOTIFY,
-        DOMAIN,
-        hass_config=hass.data[DOMAIN][DATA_HASS_CONFIG],
-    )
-
-    on_unload(
-        hass,
-        entry.entry_id,
-        async_dispatcher_connect(
-            hass,
-            MYSENSORS_DISCOVERY.format(entry.entry_id, Platform.NOTIFY),
-            load_discovery_platform,
-        ),
-    )
-
-    await hass.config_entries.async_forward_entry_setups(
-        entry, PLATFORMS_WITH_ENTRY_SUPPORT
-    )
+    await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
     await finish_setup(hass, entry, gateway)
 
     return True
@@ -95,9 +60,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
 
     gateway: BaseAsyncGateway = hass.data[DOMAIN][MYSENSORS_GATEWAYS][entry.entry_id]
 
-    unload_ok = await hass.config_entries.async_unload_platforms(
-        entry, PLATFORMS_WITH_ENTRY_SUPPORT
-    )
+    unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
     if not unload_ok:
         return False
 
diff --git a/homeassistant/components/mysensors/const.py b/homeassistant/components/mysensors/const.py
index 5368f65b83e..bcdc6f80ab2 100644
--- a/homeassistant/components/mysensors/const.py
+++ b/homeassistant/components/mysensors/const.py
@@ -40,7 +40,6 @@ class DiscoveryInfo(TypedDict):
     """Represent the discovery info type for mysensors platforms."""
 
     devices: list[DevId]
-    name: str  # CONF_NAME is used in the notify base integration.
     gateway_id: GatewayId
 
 
@@ -92,8 +91,6 @@ LIGHT_TYPES: dict[SensorType, set[ValueType]] = {
     "S_RGBW_LIGHT": {"V_RGBW"},
 }
 
-NOTIFY_TYPES: dict[SensorType, set[ValueType]] = {"S_INFO": {"V_TEXT"}}
-
 REMOTE_TYPES: dict[SensorType, set[ValueType]] = {"S_IR": {"V_IR_SEND"}}
 
 SENSOR_TYPES: dict[SensorType, set[ValueType]] = {
@@ -148,7 +145,6 @@ PLATFORM_TYPES: dict[Platform, dict[SensorType, set[ValueType]]] = {
     Platform.COVER: COVER_TYPES,
     Platform.DEVICE_TRACKER: DEVICE_TRACKER_TYPES,
     Platform.LIGHT: LIGHT_TYPES,
-    Platform.NOTIFY: NOTIFY_TYPES,
     Platform.REMOTE: REMOTE_TYPES,
     Platform.SENSOR: SENSOR_TYPES,
     Platform.SWITCH: SWITCH_TYPES,
@@ -167,6 +163,4 @@ for platform, platform_types in PLATFORM_TYPES.items():
     for s_type_name in platform_types:
         TYPE_TO_PLATFORMS[s_type_name].append(platform)
 
-PLATFORMS_WITH_ENTRY_SUPPORT = set(PLATFORM_TYPES.keys()) - {
-    Platform.NOTIFY,
-}
+PLATFORMS = tuple(PLATFORM_TYPES)
diff --git a/homeassistant/components/mysensors/notify.py b/homeassistant/components/mysensors/notify.py
deleted file mode 100644
index 97d4175a6f2..00000000000
--- a/homeassistant/components/mysensors/notify.py
+++ /dev/null
@@ -1,100 +0,0 @@
-"""MySensors notification service."""
-from __future__ import annotations
-
-from typing import Any, cast
-
-from homeassistant.components.notify import ATTR_TARGET, BaseNotificationService
-from homeassistant.const import Platform
-from homeassistant.core import HomeAssistant, callback
-from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
-from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
-from homeassistant.util import slugify
-
-from .. import mysensors
-from .const import DOMAIN, DevId, DiscoveryInfo
-
-
-async def async_get_service(
-    hass: HomeAssistant,
-    config: ConfigType,
-    discovery_info: DiscoveryInfoType | None = None,
-) -> BaseNotificationService | None:
-    """Get the MySensors notification service."""
-    if not discovery_info:
-        return None
-
-    new_devices = mysensors.setup_mysensors_platform(
-        hass,
-        Platform.NOTIFY,
-        cast(DiscoveryInfo, discovery_info),
-        MySensorsNotificationDevice,
-    )
-    if not new_devices:
-        return None
-    return MySensorsNotificationService(hass)
-
-
-class MySensorsNotificationDevice(mysensors.device.MySensorsDevice):
-    """Represent a MySensors Notification device."""
-
-    @callback
-    def _async_update_callback(self) -> None:
-        """Update the device."""
-        self._async_update()
-
-    def send_msg(self, msg: str) -> None:
-        """Send a message."""
-        for sub_msg in [msg[i : i + 25] for i in range(0, len(msg), 25)]:
-            # Max mysensors payload is 25 bytes.
-            self.gateway.set_child_value(
-                self.node_id, self.child_id, self.value_type, sub_msg
-            )
-
-    def __repr__(self) -> str:
-        """Return the representation."""
-        return f"<MySensorsNotificationDevice {self.name}>"
-
-
-class MySensorsNotificationService(BaseNotificationService):
-    """Implement a MySensors notification service."""
-
-    def __init__(self, hass: HomeAssistant) -> None:
-        """Initialize the service."""
-        self.devices: dict[
-            DevId, MySensorsNotificationDevice
-        ] = mysensors.get_mysensors_devices(
-            hass, Platform.NOTIFY
-        )  # type: ignore[assignment]
-        self.hass = hass
-
-    async def async_send_message(self, message: str = "", **kwargs: Any) -> None:
-        """Send a message to a user."""
-        target_devices = kwargs.get(ATTR_TARGET)
-        devices = [
-            device
-            for device in self.devices.values()
-            if target_devices is None or device.name in target_devices
-        ]
-
-        placeholders = {
-            "alternate_service": "text.set_value",
-            "deprecated_service": f"notify.{self._service_name}",
-            "alternate_target": str(
-                [f"text.{slugify(device.name)}" for device in devices]
-            ),
-        }
-
-        async_create_issue(
-            self.hass,
-            DOMAIN,
-            "deprecated_notify_service",
-            breaks_in_ha_version="2023.4.0",
-            is_fixable=True,
-            is_persistent=True,
-            severity=IssueSeverity.WARNING,
-            translation_key="deprecated_service",
-            translation_placeholders=placeholders,
-        )
-
-        for device in devices:
-            device.send_msg(message)
diff --git a/tests/components/mysensors/test_config_flow.py b/tests/components/mysensors/test_config_flow.py
index 98a6ae3b234..dc24a48edd4 100644
--- a/tests/components/mysensors/test_config_flow.py
+++ b/tests/components/mysensors/test_config_flow.py
@@ -61,8 +61,6 @@ async def test_config_mqtt(hass: HomeAssistant, mqtt: None) -> None:
     flow_id = step["flow_id"]
 
     with patch(
-        "homeassistant.components.mysensors.async_setup", return_value=True
-    ) as mock_setup, patch(
         "homeassistant.components.mysensors.async_setup_entry",
         return_value=True,
     ) as mock_setup_entry:
@@ -89,7 +87,6 @@ async def test_config_mqtt(hass: HomeAssistant, mqtt: None) -> None:
         CONF_VERSION: "2.4",
         CONF_GATEWAY_TYPE: "MQTT",
     }
-    assert len(mock_setup.mock_calls) == 1
     assert len(mock_setup_entry.mock_calls) == 1
 
 
@@ -121,8 +118,6 @@ async def test_config_serial(hass: HomeAssistant) -> None:
     ), patch(
         "homeassistant.components.mysensors.config_flow.try_connect", return_value=True
     ), patch(
-        "homeassistant.components.mysensors.async_setup", return_value=True
-    ) as mock_setup, patch(
         "homeassistant.components.mysensors.async_setup_entry",
         return_value=True,
     ) as mock_setup_entry:
@@ -146,7 +141,6 @@ async def test_config_serial(hass: HomeAssistant) -> None:
         CONF_VERSION: "2.4",
         CONF_GATEWAY_TYPE: "Serial",
     }
-    assert len(mock_setup.mock_calls) == 1
     assert len(mock_setup_entry.mock_calls) == 1
 
 
@@ -158,8 +152,6 @@ async def test_config_tcp(hass: HomeAssistant) -> None:
     with patch(
         "homeassistant.components.mysensors.config_flow.try_connect", return_value=True
     ), patch(
-        "homeassistant.components.mysensors.async_setup", return_value=True
-    ) as mock_setup, patch(
         "homeassistant.components.mysensors.async_setup_entry",
         return_value=True,
     ) as mock_setup_entry:
@@ -183,7 +175,6 @@ async def test_config_tcp(hass: HomeAssistant) -> None:
         CONF_VERSION: "2.4",
         CONF_GATEWAY_TYPE: "TCP",
     }
-    assert len(mock_setup.mock_calls) == 1
     assert len(mock_setup_entry.mock_calls) == 1
 
 
@@ -195,8 +186,6 @@ async def test_fail_to_connect(hass: HomeAssistant) -> None:
     with patch(
         "homeassistant.components.mysensors.config_flow.try_connect", return_value=False
     ), patch(
-        "homeassistant.components.mysensors.async_setup", return_value=True
-    ) as mock_setup, patch(
         "homeassistant.components.mysensors.async_setup_entry",
         return_value=True,
     ) as mock_setup_entry:
@@ -215,7 +204,6 @@ async def test_fail_to_connect(hass: HomeAssistant) -> None:
     errors = result["errors"]
     assert errors
     assert errors.get("base") == "cannot_connect"
-    assert len(mock_setup.mock_calls) == 0
     assert len(mock_setup_entry.mock_calls) == 0
 
 
@@ -358,8 +346,6 @@ async def test_config_invalid(
         "homeassistant.components.mysensors.gateway.socket.getaddrinfo",
         side_effect=OSError,
     ), patch(
-        "homeassistant.components.mysensors.async_setup", return_value=True
-    ) as mock_setup, patch(
         "homeassistant.components.mysensors.async_setup_entry",
         return_value=True,
     ) as mock_setup_entry:
@@ -375,7 +361,6 @@ async def test_config_invalid(
     assert errors
     assert err_field in errors
     assert errors[err_field] == err_string
-    assert len(mock_setup.mock_calls) == 0
     assert len(mock_setup_entry.mock_calls) == 0
 
 
diff --git a/tests/components/mysensors/test_notify.py b/tests/components/mysensors/test_notify.py
deleted file mode 100644
index e96b463cc78..00000000000
--- a/tests/components/mysensors/test_notify.py
+++ /dev/null
@@ -1,95 +0,0 @@
-"""Provide tests for mysensors notify platform."""
-from __future__ import annotations
-
-from collections.abc import Callable
-from unittest.mock import MagicMock, call
-
-from mysensors.sensor import Sensor
-
-from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN
-from homeassistant.core import HomeAssistant
-
-from tests.common import MockConfigEntry
-
-
-async def test_text_type(
-    hass: HomeAssistant,
-    text_node: Sensor,
-    transport_write: MagicMock,
-    integration: MockConfigEntry,
-) -> None:
-    """Test a text type child."""
-    # Test without target.
-    await hass.services.async_call(
-        NOTIFY_DOMAIN, "mysensors", {"message": "Hello World"}, blocking=True
-    )
-
-    assert transport_write.call_count == 1
-    assert transport_write.call_args == call("1;1;1;0;47;Hello World\n")
-
-    # Test with target.
-    await hass.services.async_call(
-        NOTIFY_DOMAIN,
-        "mysensors",
-        {"message": "Hello", "target": "Text Node 1 1"},
-        blocking=True,
-    )
-
-    assert transport_write.call_count == 2
-    assert transport_write.call_args == call("1;1;1;0;47;Hello\n")
-
-    transport_write.reset_mock()
-
-    # Test a message longer than 25 characters.
-    await hass.services.async_call(
-        NOTIFY_DOMAIN,
-        "mysensors",
-        {
-            "message": "This is a long message that will be split",
-            "target": "Text Node 1 1",
-        },
-        blocking=True,
-    )
-
-    assert transport_write.call_count == 2
-    assert transport_write.call_args_list == [
-        call("1;1;1;0;47;This is a long message th\n"),
-        call("1;1;1;0;47;at will be split\n"),
-    ]
-
-
-async def test_text_type_discovery(
-    hass: HomeAssistant,
-    text_node: Sensor,
-    transport_write: MagicMock,
-    receive_message: Callable[[str], None],
-) -> None:
-    """Test text type discovery."""
-    receive_message("1;2;0;0;36;\n")
-    receive_message("1;2;1;0;47;test\n")
-    receive_message("1;2;1;0;47;test2\n")  # Test that more than one set message works.
-    await hass.async_block_till_done()
-
-    # Test targeting the discovered child.
-    await hass.services.async_call(
-        NOTIFY_DOMAIN,
-        "mysensors",
-        {"message": "Hello", "target": "Text Node 1 2"},
-        blocking=True,
-    )
-
-    assert transport_write.call_count == 1
-    assert transport_write.call_args == call("1;2;1;0;47;Hello\n")
-
-    transport_write.reset_mock()
-
-    # Test targeting all notify children.
-    await hass.services.async_call(
-        NOTIFY_DOMAIN, "mysensors", {"message": "Hello World"}, blocking=True
-    )
-
-    assert transport_write.call_count == 2
-    assert transport_write.call_args_list == [
-        call("1;1;1;0;47;Hello World\n"),
-        call("1;2;1;0;47;Hello World\n"),
-    ]
-- 
GitLab