Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow per-sensor unit conversion on BMW sensors #110272

Merged
merged 20 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Revert enum sensor changes
  • Loading branch information
rikroe committed Jun 3, 2024
commit 500281e75da776b69d8da35d472f8efe8b8c793e
7 changes: 7 additions & 0 deletions homeassistant/components/bmw_connected_drive/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,10 @@
"north_america": 600,
"rest_of_world": 300,
}

CLIMATE_ACTIVITY_STATE: list[str] = [
"cooling",
"heating",
"inactive",
"standby",
]
19 changes: 7 additions & 12 deletions homeassistant/components/bmw_connected_drive/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

from bimmer_connected.models import StrEnum, ValueWithUnit
from bimmer_connected.vehicle import MyBMWVehicle
from bimmer_connected.vehicle.climate import ClimateActivityState
from bimmer_connected.vehicle.fuel_and_battery import ChargingState

from homeassistant.components.sensor import (
SensorDeviceClass,
Expand All @@ -31,7 +29,7 @@
from homeassistant.util import dt as dt_util

from . import BMWBaseEntity
from .const import DOMAIN
from .const import CLIMATE_ACTIVITY_STATE, DOMAIN
from .coordinator import BMWDataUpdateCoordinator

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -75,8 +73,6 @@ class BMWSensorEntityDescription(SensorEntityDescription):
key="charging_status",
translation_key="charging_status",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.ENUM,
options=[s.value.lower() for s in ChargingState if s != ChargingState.UNKNOWN],
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
),
BMWSensorEntityDescription(
Expand All @@ -98,7 +94,6 @@ class BMWSensorEntityDescription(SensorEntityDescription):
suggested_display_precision=0,
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
),
# --- Specific ---
BMWSensorEntityDescription(
key="mileage",
translation_key="mileage",
Expand Down Expand Up @@ -160,11 +155,7 @@ class BMWSensorEntityDescription(SensorEntityDescription):
translation_key="climate_status",
key_class="climate",
device_class=SensorDeviceClass.ENUM,
options=[
s.value.lower()
for s in ClimateActivityState
if s != ClimateActivityState.UNKNOWN
],
options=CLIMATE_ACTIVITY_STATE,
is_available=lambda v: v.is_remote_climate_stop_enabled,
),
]
Expand Down Expand Up @@ -224,11 +215,15 @@ def _handle_coordinator_update(self) -> None:
# For enum types, we only want the value
elif isinstance(state, ValueWithUnit):
state = state.value
# Special handling for string enums
# Get lowercase values from StrEnum
elif isinstance(state, StrEnum):
state = state.value.lower()
if state == STATE_UNKNOWN:
state = None

# special handling for charging_status to avoid a breaking change
if self.entity_description.key == "charging_status" and state:
state = state.upper()

self._attr_native_value = state
super()._handle_coordinator_update()
16 changes: 1 addition & 15 deletions homeassistant/components/bmw_connected_drive/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,7 @@
"name": "Charging end time"
},
"charging_status": {
"name": "Charging status",
"state": {
"default": "Default",
"charging": "Charging",
"error": "Error",
"complete": "Complete",
"fully_charged": "Fully charged",
"finished_fully_charged": "Finished, fully charged",
"finished_not_full": "Finished, not full",
"invalid": "Invalid",
"not_charging": "Not charging",
"plugged_in": "Plugged in",
"waiting_for_charging": "Waiting for charging",
"target_reached": "Target reached"
}
"name": "Charging status"
},
"charging_target": {
"name": "Charging target"
Expand Down
108 changes: 9 additions & 99 deletions tests/components/bmw_connected_drive/snapshots/test_sensor.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -152,22 +152,7 @@
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'default',
'charging',
'error',
'complete',
'fully_charged',
'finished_fully_charged',
'finished_not_full',
'invalid',
'not_charging',
'plugged_in',
'waiting_for_charging',
'target_reached',
]),
}),
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
Expand All @@ -184,7 +169,7 @@
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_device_class': None,
'original_icon': None,
'original_name': 'Charging status',
'platform': 'bmw_connected_drive',
Expand All @@ -199,29 +184,14 @@
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by MyBMW',
'device_class': 'enum',
'friendly_name': 'i3 (+ REX) Charging status',
'options': list([
'default',
'charging',
'error',
'complete',
'fully_charged',
'finished_fully_charged',
'finished_not_full',
'invalid',
'not_charging',
'plugged_in',
'waiting_for_charging',
'target_reached',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.i3_rex_charging_status',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'waiting_for_charging',
'state': 'WAITING_FOR_CHARGING',
})
# ---
# name: test_entity_state_attrs[sensor.i3_rex_charging_target-entry]
Expand Down Expand Up @@ -813,22 +783,7 @@
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'default',
'charging',
'error',
'complete',
'fully_charged',
'finished_fully_charged',
'finished_not_full',
'invalid',
'not_charging',
'plugged_in',
'waiting_for_charging',
'target_reached',
]),
}),
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
Expand All @@ -845,7 +800,7 @@
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_device_class': None,
'original_icon': None,
'original_name': 'Charging status',
'platform': 'bmw_connected_drive',
Expand All @@ -860,29 +815,14 @@
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by MyBMW',
'device_class': 'enum',
'friendly_name': 'i4 eDrive40 Charging status',
'options': list([
'default',
'charging',
'error',
'complete',
'fully_charged',
'finished_fully_charged',
'finished_not_full',
'invalid',
'not_charging',
'plugged_in',
'waiting_for_charging',
'target_reached',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.i4_edrive40_charging_status',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'not_charging',
'state': 'NOT_CHARGING',
})
# ---
# name: test_entity_state_attrs[sensor.i4_edrive40_charging_target-entry]
Expand Down Expand Up @@ -1371,22 +1311,7 @@
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'default',
'charging',
'error',
'complete',
'fully_charged',
'finished_fully_charged',
'finished_not_full',
'invalid',
'not_charging',
'plugged_in',
'waiting_for_charging',
'target_reached',
]),
}),
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
Expand All @@ -1403,7 +1328,7 @@
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_device_class': None,
'original_icon': None,
'original_name': 'Charging status',
'platform': 'bmw_connected_drive',
Expand All @@ -1418,29 +1343,14 @@
StateSnapshot({
'attributes': ReadOnlyDict({
'attribution': 'Data provided by MyBMW',
'device_class': 'enum',
'friendly_name': 'iX xDrive50 Charging status',
'options': list([
'default',
'charging',
'error',
'complete',
'fully_charged',
'finished_fully_charged',
'finished_not_full',
'invalid',
'not_charging',
'plugged_in',
'waiting_for_charging',
'target_reached',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.ix_xdrive50_charging_status',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'charging',
'state': 'CHARGING',
})
# ---
# name: test_entity_state_attrs[sensor.ix_xdrive50_charging_target-entry]
Expand Down
Loading