Skip to content

Commit

Permalink
Refactor BMW sensor state retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
rikroe committed Jul 1, 2024
1 parent f672eec commit 7cf2c6f
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 38 deletions.
16 changes: 14 additions & 2 deletions homeassistant/components/bmw_connected_drive/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,20 @@ async def _async_migrate_entries(
@callback
def update_unique_id(entry: er.RegistryEntry) -> dict[str, str] | None:
replacements = {
"charging_level_hv": "remaining_battery_percent",
"fuel_percent": "remaining_fuel_percent",
"charging_level_hv": "fuel_and_battery.remaining_battery_percent",
"fuel_percent": "fuel_and_battery.remaining_fuel_percent",
"ac_current_limit": "charging_profile.ac_current_limit",
"charging_start_time": "fuel_and_battery.charging_start_time",
"charging_end_time": "fuel_and_battery.charging_end_time",
"charging_status": "fuel_and_battery.charging_status",
"charging_target": "fuel_and_battery.charging_target",
"remaining_battery_percent": "fuel_and_battery.remaining_battery_percent",
"remaining_range_total": "fuel_and_battery.remaining_range_total",
"remaining_range_electric": "fuel_and_battery.remaining_range_electric",
"remaining_range_fuel": "fuel_and_battery.remaining_range_fuel",
"remaining_fuel": "fuel_and_battery.remaining_fuel",
"remaining_fuel_percent": "fuel_and_battery.remaining_fuel_percent",
"activity": "climate.activity",
}
if (key := entry.unique_id.split("-")[-1]) in replacements:
new_unique_id = entry.unique_id.replace(key, replacements[key])
Expand Down
49 changes: 18 additions & 31 deletions homeassistant/components/bmw_connected_drive/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,51 +45,45 @@ class BMWSensorEntityDescription(SensorEntityDescription):

SENSOR_TYPES: list[BMWSensorEntityDescription] = [
BMWSensorEntityDescription(
key="ac_current_limit",
key="charging_profile.ac_current_limit",
translation_key="ac_current_limit",
key_class="charging_profile",
device_class=SensorDeviceClass.CURRENT,
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
entity_registry_enabled_default=False,
suggested_display_precision=0,
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
),
BMWSensorEntityDescription(
key="charging_start_time",
key="fuel_and_battery.charging_start_time",
translation_key="charging_start_time",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.TIMESTAMP,
entity_registry_enabled_default=False,
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
),
BMWSensorEntityDescription(
key="charging_end_time",
key="fuel_and_battery.charging_end_time",
translation_key="charging_end_time",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.TIMESTAMP,
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
),
BMWSensorEntityDescription(
key="charging_status",
key="fuel_and_battery.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(
key="charging_target",
key="fuel_and_battery.charging_target",
translation_key="charging_target",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.BATTERY,
native_unit_of_measurement=PERCENTAGE,
suggested_display_precision=0,
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
),
BMWSensorEntityDescription(
key="remaining_battery_percent",
key="fuel_and_battery.remaining_battery_percent",
translation_key="remaining_battery_percent",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.BATTERY,
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
Expand All @@ -105,57 +99,51 @@ class BMWSensorEntityDescription(SensorEntityDescription):
suggested_display_precision=0,
),
BMWSensorEntityDescription(
key="remaining_range_total",
key="fuel_and_battery.remaining_range_total",
translation_key="remaining_range_total",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.DISTANCE,
native_unit_of_measurement=UnitOfLength.KILOMETERS,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
),
BMWSensorEntityDescription(
key="remaining_range_electric",
key="fuel_and_battery.remaining_range_electric",
translation_key="remaining_range_electric",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.DISTANCE,
native_unit_of_measurement=UnitOfLength.KILOMETERS,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
),
BMWSensorEntityDescription(
key="remaining_range_fuel",
key="fuel_and_battery.remaining_range_fuel",
translation_key="remaining_range_fuel",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.DISTANCE,
native_unit_of_measurement=UnitOfLength.KILOMETERS,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
is_available=lambda v: v.is_lsc_enabled and v.has_combustion_drivetrain,
),
BMWSensorEntityDescription(
key="remaining_fuel",
key="fuel_and_battery.remaining_fuel",
translation_key="remaining_fuel",
key_class="fuel_and_battery",
device_class=SensorDeviceClass.VOLUME,
native_unit_of_measurement=UnitOfVolume.LITERS,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
is_available=lambda v: v.is_lsc_enabled and v.has_combustion_drivetrain,
),
BMWSensorEntityDescription(
key="remaining_fuel_percent",
key="fuel_and_battery.remaining_fuel_percent",
translation_key="remaining_fuel_percent",
key_class="fuel_and_battery",
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
suggested_display_precision=0,
is_available=lambda v: v.is_lsc_enabled and v.has_combustion_drivetrain,
),
BMWSensorEntityDescription(
key="activity",
key="climate.activity",
translation_key="climate_status",
key_class="climate",
device_class=SensorDeviceClass.ENUM,
options=[
s.value.lower()
Expand Down Expand Up @@ -207,13 +195,12 @@ def _handle_coordinator_update(self) -> None:
_LOGGER.debug(
"Updating sensor '%s' of %s", self.entity_description.key, self.vehicle.name
)
if self.entity_description.key_class is None:
state = getattr(self.vehicle, self.entity_description.key)
else:
state = getattr(
getattr(self.vehicle, self.entity_description.key_class),
self.entity_description.key,
)

key_path = self.entity_description.key.split(".")
state = getattr(self.vehicle, key_path.pop(0))

for key in key_path:
state = getattr(state, key)

# For datetime without tzinfo, we assume it to be the same timezone as the HA instance
if isinstance(state, datetime.datetime) and state.tzinfo is None:
Expand Down
21 changes: 16 additions & 5 deletions tests/components/bmw_connected_drive/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ async def test_migrate_options_from_data(hass: HomeAssistant) -> None:
"disabled_by": None,
},
f"{VIN}-charging_level_hv",
f"{VIN}-remaining_battery_percent",
f"{VIN}-fuel_and_battery.remaining_battery_percent",
),
(
{
Expand All @@ -96,7 +96,18 @@ async def test_migrate_options_from_data(hass: HomeAssistant) -> None:
"disabled_by": None,
},
f"{VIN}-remaining_range_total",
f"{VIN}-remaining_range_total",
f"{VIN}-fuel_and_battery.remaining_range_total",
),
(
{
"domain": SENSOR_DOMAIN,
"platform": BMW_DOMAIN,
"unique_id": f"{VIN}-mileage",
"suggested_object_id": f"{VEHICLE_NAME} mileage",
"disabled_by": None,
},
f"{VIN}-mileage",
f"{VIN}-mileage",
),
],
)
Expand Down Expand Up @@ -143,7 +154,7 @@ async def test_migrate_unique_ids(
"disabled_by": None,
},
f"{VIN}-charging_level_hv",
f"{VIN}-remaining_battery_percent",
f"{VIN}-fuel_and_battery.remaining_battery_percent",
),
],
)
Expand All @@ -163,8 +174,8 @@ async def test_dont_migrate_unique_ids(
existing_entity = entity_registry.async_get_or_create(
SENSOR_DOMAIN,
BMW_DOMAIN,
unique_id=f"{VIN}-remaining_battery_percent",
suggested_object_id=f"{VEHICLE_NAME} remaining_battery_percent",
unique_id=f"{VIN}-fuel_and_battery.remaining_battery_percent",
suggested_object_id=f"{VEHICLE_NAME} fuel_and_battery.remaining_battery_percent",
config_entry=mock_config_entry,
)

Expand Down

0 comments on commit 7cf2c6f

Please sign in to comment.