From fa485513d5fbcd0cd1ca79ce90d4ab845bb076f9 Mon Sep 17 00:00:00 2001
From: Franck Nijhof <git@frenck.dev>
Date: Sun, 21 Jan 2024 12:02:15 +0100
Subject: [PATCH] Ensure icon translations aren't the same as the default
 (#108568)

---
 homeassistant/components/cover/icons.json     |  8 +---
 .../components/media_player/icons.json        |  2 +-
 homeassistant/components/weather/icons.json   |  1 -
 script/hassfest/icons.py                      | 43 ++++++++++++++-----
 4 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/homeassistant/components/cover/icons.json b/homeassistant/components/cover/icons.json
index d450070e631..f2edaaa0893 100644
--- a/homeassistant/components/cover/icons.json
+++ b/homeassistant/components/cover/icons.json
@@ -27,17 +27,13 @@
     "damper": {
       "default": "mdi:circle",
       "state": {
-        "closed": "mdi:circle-slice-8",
-        "closing": "mdi:circle",
-        "opening": "mdi:circle"
+        "closed": "mdi:circle-slice-8"
       }
     },
     "door": {
       "default": "mdi:door-open",
       "state": {
-        "closed": "mdi:door-closed",
-        "closing": "mdi:door-open",
-        "opening": "mdi:door-open"
+        "closed": "mdi:door-closed"
       }
     },
     "garage": {
diff --git a/homeassistant/components/media_player/icons.json b/homeassistant/components/media_player/icons.json
index b79c66af0e9..e2769085833 100644
--- a/homeassistant/components/media_player/icons.json
+++ b/homeassistant/components/media_player/icons.json
@@ -3,7 +3,7 @@
     "_": {
       "default": "mdi:cast",
       "state": {
-        "off": "mdi:cast",
+        "off": "mdi:cast-off",
         "paused": "mdi:cast-connected",
         "playing": "mdi:cast-connected"
       }
diff --git a/homeassistant/components/weather/icons.json b/homeassistant/components/weather/icons.json
index 63daae20e3c..cc53861e700 100644
--- a/homeassistant/components/weather/icons.json
+++ b/homeassistant/components/weather/icons.json
@@ -10,7 +10,6 @@
         "hail": "mdi:weather-hail",
         "lightning": "mdi:weather-lightning",
         "lightning-rainy": "mdi:weather-lightning-rainy",
-        "partlycloudy": "mdi:weather-partly-cloudy",
         "pouring": "mdi:weather-pouring",
         "rainy": "mdi:weather-rainy",
         "snowy": "mdi:weather-snowy",
diff --git a/script/hassfest/icons.py b/script/hassfest/icons.py
index 1b993ddece3..f5e07a0d348 100644
--- a/script/hassfest/icons.py
+++ b/script/hassfest/icons.py
@@ -32,6 +32,20 @@ def require_default_icon_validator(value: dict) -> dict:
     return value
 
 
+def ensure_not_same_as_default(value: dict) -> dict:
+    """Validate an icon isn't the same as its default icon."""
+    for translation_key, section in value.items():
+        if (default := section.get("default")) and (states := section.get("state")):
+            for state, icon in states.items():
+                if icon == default:
+                    raise vol.Invalid(
+                        f"The icon for state `{translation_key}.{state}` is the"
+                        " same as the default icon and thus can be removed"
+                    )
+
+    return value
+
+
 def icon_schema(integration_type: str) -> vol.Schema:
     """Create a icon schema."""
 
@@ -44,12 +58,15 @@ def icon_schema(integration_type: str) -> vol.Schema:
         return {
             marker("default"): icon_value_validator,
             vol.Optional("state"): state_validator,
-            vol.Optional("state_attributes"): cv.schema_with_slug_keys(
-                {
-                    marker("default"): icon_value_validator,
-                    marker("state"): state_validator,
-                },
-                slug_validator=translation_key_validator,
+            vol.Optional("state_attributes"): vol.All(
+                cv.schema_with_slug_keys(
+                    {
+                        marker("default"): icon_value_validator,
+                        marker("state"): state_validator,
+                    },
+                    slug_validator=translation_key_validator,
+                ),
+                ensure_not_same_as_default,
             ),
         }
 
@@ -68,18 +85,22 @@ def icon_schema(integration_type: str) -> vol.Schema:
                         slug_validator=vol.Any("_", cv.slug),
                     ),
                     require_default_icon_validator,
+                    ensure_not_same_as_default,
                 )
             }
         )
     return base_schema.extend(
         {
-            vol.Optional("entity"): cv.schema_with_slug_keys(
+            vol.Optional("entity"): vol.All(
                 cv.schema_with_slug_keys(
-                    icon_schema_slug(vol.Optional),
-                    slug_validator=translation_key_validator,
+                    cv.schema_with_slug_keys(
+                        icon_schema_slug(vol.Optional),
+                        slug_validator=translation_key_validator,
+                    ),
+                    slug_validator=cv.slug,
                 ),
-                slug_validator=cv.slug,
-            ),
+                ensure_not_same_as_default,
+            )
         }
     )
 
-- 
GitLab