From a99ecb024eef0ded73a467f71af9d672f31c60ae Mon Sep 17 00:00:00 2001
From: brave0d <138725265+brave0d@users.noreply.github.com>
Date: Tue, 16 Apr 2024 08:24:32 +0100
Subject: [PATCH] New BMW sensor for climate activity (#110287)

* add sensor with climate activity status

* Update strings.json

* use icon translation and is_available for sensor

* use enum with translations

* Return None if value is UNKNOWN

* fix getting the value: x.value

* fix getting the value: x instead of x.value

* Fix tests and pre-commit

---------

Co-authored-by: Richard <rikroe@users.noreply.github.com>
---
 .../components/bmw_connected_drive/const.py   |  7 +++
 .../components/bmw_connected_drive/icons.json |  3 +
 .../components/bmw_connected_drive/sensor.py  | 11 +++-
 .../bmw_connected_drive/strings.json          |  9 +++
 .../snapshots/test_sensor.ambr                | 57 +++++++++++++++++++
 5 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/homeassistant/components/bmw_connected_drive/const.py b/homeassistant/components/bmw_connected_drive/const.py
index 49990977f71..5374b52e684 100644
--- a/homeassistant/components/bmw_connected_drive/const.py
+++ b/homeassistant/components/bmw_connected_drive/const.py
@@ -28,3 +28,10 @@ SCAN_INTERVALS = {
     "north_america": 600,
     "rest_of_world": 300,
 }
+
+CLIMATE_ACTIVITY_STATE: list[str] = [
+    "cooling",
+    "heating",
+    "inactive",
+    "standby",
+]
diff --git a/homeassistant/components/bmw_connected_drive/icons.json b/homeassistant/components/bmw_connected_drive/icons.json
index a4eb37b369a..fc30b87ed3f 100644
--- a/homeassistant/components/bmw_connected_drive/icons.json
+++ b/homeassistant/components/bmw_connected_drive/icons.json
@@ -85,6 +85,9 @@
       },
       "remaining_fuel_percent": {
         "default": "mdi:gas-station"
+      },
+      "climate_status": {
+        "default": "mdi:fan"
       }
     },
     "switch": {
diff --git a/homeassistant/components/bmw_connected_drive/sensor.py b/homeassistant/components/bmw_connected_drive/sensor.py
index e1ed398cfec..d3366543c55 100644
--- a/homeassistant/components/bmw_connected_drive/sensor.py
+++ b/homeassistant/components/bmw_connected_drive/sensor.py
@@ -23,7 +23,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
 from homeassistant.helpers.typing import StateType
 
 from . import BMWBaseEntity
-from .const import DOMAIN, UNIT_MAP
+from .const import CLIMATE_ACTIVITY_STATE, DOMAIN, UNIT_MAP
 from .coordinator import BMWDataUpdateCoordinator
 
 _LOGGER = logging.getLogger(__name__)
@@ -153,6 +153,15 @@ SENSOR_TYPES: list[BMWSensorEntityDescription] = [
         state_class=SensorStateClass.MEASUREMENT,
         is_available=lambda v: v.is_lsc_enabled and v.has_combustion_drivetrain,
     ),
+    BMWSensorEntityDescription(
+        key="activity",
+        translation_key="climate_status",
+        key_class="climate",
+        device_class=SensorDeviceClass.ENUM,
+        options=CLIMATE_ACTIVITY_STATE,
+        value=lambda x, _: x.lower() if x != "UNKNOWN" else None,
+        is_available=lambda v: v.is_remote_climate_stop_enabled,
+    ),
 ]
 
 
diff --git a/homeassistant/components/bmw_connected_drive/strings.json b/homeassistant/components/bmw_connected_drive/strings.json
index 69abd97ddfe..539c281a1a5 100644
--- a/homeassistant/components/bmw_connected_drive/strings.json
+++ b/homeassistant/components/bmw_connected_drive/strings.json
@@ -122,6 +122,15 @@
       },
       "remaining_fuel_percent": {
         "name": "Remaining fuel percent"
+      },
+      "climate_status": {
+        "name": "Climate status",
+        "state": {
+          "cooling": "Cooling",
+          "heating": "Heating",
+          "inactive": "Inactive",
+          "standby": "Standby"
+        }
       }
     },
     "switch": {
diff --git a/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr b/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr
index c9dd4e3ddb8..dcf68622fdc 100644
--- a/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr
+++ b/tests/components/bmw_connected_drive/snapshots/test_sensor.ambr
@@ -96,6 +96,25 @@
       'last_updated': <ANY>,
       'state': '340',
     }),
+    StateSnapshot({
+      'attributes': ReadOnlyDict({
+        'attribution': 'Data provided by MyBMW',
+        'device_class': 'enum',
+        'friendly_name': 'iX xDrive50 Climate status',
+        'options': list([
+          'cooling',
+          'heating',
+          'inactive',
+          'standby',
+        ]),
+      }),
+      'context': <ANY>,
+      'entity_id': 'sensor.ix_xdrive50_climate_status',
+      'last_changed': <ANY>,
+      'last_reported': <ANY>,
+      'last_updated': <ANY>,
+      'state': 'inactive',
+    }),
     StateSnapshot({
       'attributes': ReadOnlyDict({
         'attribution': 'Data provided by MyBMW',
@@ -191,6 +210,25 @@
       'last_updated': <ANY>,
       'state': '472',
     }),
+    StateSnapshot({
+      'attributes': ReadOnlyDict({
+        'attribution': 'Data provided by MyBMW',
+        'device_class': 'enum',
+        'friendly_name': 'i4 eDrive40 Climate status',
+        'options': list([
+          'cooling',
+          'heating',
+          'inactive',
+          'standby',
+        ]),
+      }),
+      'context': <ANY>,
+      'entity_id': 'sensor.i4_edrive40_climate_status',
+      'last_changed': <ANY>,
+      'last_reported': <ANY>,
+      'last_updated': <ANY>,
+      'state': 'heating',
+    }),
     StateSnapshot({
       'attributes': ReadOnlyDict({
         'attribution': 'Data provided by MyBMW',
@@ -261,6 +299,25 @@
       'last_updated': <ANY>,
       'state': '80',
     }),
+    StateSnapshot({
+      'attributes': ReadOnlyDict({
+        'attribution': 'Data provided by MyBMW',
+        'device_class': 'enum',
+        'friendly_name': 'M340i xDrive Climate status',
+        'options': list([
+          'cooling',
+          'heating',
+          'inactive',
+          'standby',
+        ]),
+      }),
+      'context': <ANY>,
+      'entity_id': 'sensor.m340i_xdrive_climate_status',
+      'last_changed': <ANY>,
+      'last_reported': <ANY>,
+      'last_updated': <ANY>,
+      'state': 'inactive',
+    }),
     StateSnapshot({
       'attributes': ReadOnlyDict({
         'attribution': 'Data provided by MyBMW',
-- 
GitLab