mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Refactor BMW entity availability (#110294)
Co-authored-by: Richard <rikroe@users.noreply.github.com>
This commit is contained in:
parent
487480dc88
commit
16fc935c87
@ -116,6 +116,7 @@ class BMWBinarySensorEntityDescription(BinarySensorEntityDescription):
|
|||||||
|
|
||||||
value_fn: Callable[[MyBMWVehicle], bool]
|
value_fn: Callable[[MyBMWVehicle], bool]
|
||||||
attr_fn: Callable[[MyBMWVehicle, UnitSystem], dict[str, Any]] | None = None
|
attr_fn: Callable[[MyBMWVehicle, UnitSystem], dict[str, Any]] | None = None
|
||||||
|
is_available: Callable[[MyBMWVehicle], bool] = lambda v: v.is_lsc_enabled
|
||||||
|
|
||||||
|
|
||||||
SENSOR_TYPES: tuple[BMWBinarySensorEntityDescription, ...] = (
|
SENSOR_TYPES: tuple[BMWBinarySensorEntityDescription, ...] = (
|
||||||
@ -174,12 +175,14 @@ SENSOR_TYPES: tuple[BMWBinarySensorEntityDescription, ...] = (
|
|||||||
device_class=BinarySensorDeviceClass.BATTERY_CHARGING,
|
device_class=BinarySensorDeviceClass.BATTERY_CHARGING,
|
||||||
# device class power: On means power detected, Off means no power
|
# device class power: On means power detected, Off means no power
|
||||||
value_fn=lambda v: v.fuel_and_battery.charging_status == ChargingState.CHARGING,
|
value_fn=lambda v: v.fuel_and_battery.charging_status == ChargingState.CHARGING,
|
||||||
|
is_available=lambda v: v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
BMWBinarySensorEntityDescription(
|
BMWBinarySensorEntityDescription(
|
||||||
key="connection_status",
|
key="connection_status",
|
||||||
translation_key="connection_status",
|
translation_key="connection_status",
|
||||||
device_class=BinarySensorDeviceClass.PLUG,
|
device_class=BinarySensorDeviceClass.PLUG,
|
||||||
value_fn=lambda v: v.fuel_and_battery.is_charger_connected,
|
value_fn=lambda v: v.fuel_and_battery.is_charger_connected,
|
||||||
|
is_available=lambda v: v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
BMWBinarySensorEntityDescription(
|
BMWBinarySensorEntityDescription(
|
||||||
key="is_pre_entry_climatization_enabled",
|
key="is_pre_entry_climatization_enabled",
|
||||||
@ -187,6 +190,7 @@ SENSOR_TYPES: tuple[BMWBinarySensorEntityDescription, ...] = (
|
|||||||
value_fn=lambda v: v.charging_profile.is_pre_entry_climatization_enabled
|
value_fn=lambda v: v.charging_profile.is_pre_entry_climatization_enabled
|
||||||
if v.charging_profile
|
if v.charging_profile
|
||||||
else False,
|
else False,
|
||||||
|
is_available=lambda v: v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -203,7 +207,7 @@ async def async_setup_entry(
|
|||||||
BMWBinarySensor(coordinator, vehicle, description, hass.config.units)
|
BMWBinarySensor(coordinator, vehicle, description, hass.config.units)
|
||||||
for vehicle in coordinator.account.vehicles
|
for vehicle in coordinator.account.vehicles
|
||||||
for description in SENSOR_TYPES
|
for description in SENSOR_TYPES
|
||||||
if description.key in vehicle.available_attributes
|
if description.is_available(vehicle)
|
||||||
]
|
]
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class BMWLock(BMWBaseEntity, LockEntity):
|
|||||||
super().__init__(coordinator, vehicle)
|
super().__init__(coordinator, vehicle)
|
||||||
|
|
||||||
self._attr_unique_id = f"{vehicle.vin}-lock"
|
self._attr_unique_id = f"{vehicle.vin}-lock"
|
||||||
self.door_lock_state_available = DOOR_LOCK_STATE in vehicle.available_attributes
|
self.door_lock_state_available = vehicle.is_lsc_enabled
|
||||||
|
|
||||||
async def async_lock(self, **kwargs: Any) -> None:
|
async def async_lock(self, **kwargs: Any) -> None:
|
||||||
"""Lock the car."""
|
"""Lock the car."""
|
||||||
|
@ -36,6 +36,7 @@ class BMWSensorEntityDescription(SensorEntityDescription):
|
|||||||
key_class: str | None = None
|
key_class: str | None = None
|
||||||
unit_type: str | None = None
|
unit_type: str | None = None
|
||||||
value: Callable = lambda x, y: x
|
value: Callable = lambda x, y: x
|
||||||
|
is_available: Callable[[MyBMWVehicle], bool] = lambda v: v.is_lsc_enabled
|
||||||
|
|
||||||
|
|
||||||
def convert_and_round(
|
def convert_and_round(
|
||||||
@ -53,57 +54,63 @@ def convert_and_round(
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
SENSOR_TYPES: dict[str, BMWSensorEntityDescription] = {
|
SENSOR_TYPES: list[BMWSensorEntityDescription] = [
|
||||||
# --- Generic ---
|
# --- Generic ---
|
||||||
"ac_current_limit": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="ac_current_limit",
|
key="ac_current_limit",
|
||||||
translation_key="ac_current_limit",
|
translation_key="ac_current_limit",
|
||||||
key_class="charging_profile",
|
key_class="charging_profile",
|
||||||
unit_type=UnitOfElectricCurrent.AMPERE,
|
unit_type=UnitOfElectricCurrent.AMPERE,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
"charging_start_time": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="charging_start_time",
|
key="charging_start_time",
|
||||||
translation_key="charging_start_time",
|
translation_key="charging_start_time",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
entity_registry_enabled_default=False,
|
entity_registry_enabled_default=False,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
"charging_end_time": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="charging_end_time",
|
key="charging_end_time",
|
||||||
translation_key="charging_end_time",
|
translation_key="charging_end_time",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
device_class=SensorDeviceClass.TIMESTAMP,
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
"charging_status": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="charging_status",
|
key="charging_status",
|
||||||
translation_key="charging_status",
|
translation_key="charging_status",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
value=lambda x, y: x.value,
|
value=lambda x, y: x.value,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
"charging_target": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="charging_target",
|
key="charging_target",
|
||||||
translation_key="charging_target",
|
translation_key="charging_target",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
unit_type=PERCENTAGE,
|
unit_type=PERCENTAGE,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
"remaining_battery_percent": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="remaining_battery_percent",
|
key="remaining_battery_percent",
|
||||||
translation_key="remaining_battery_percent",
|
translation_key="remaining_battery_percent",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
unit_type=PERCENTAGE,
|
unit_type=PERCENTAGE,
|
||||||
device_class=SensorDeviceClass.BATTERY,
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
# --- Specific ---
|
# --- Specific ---
|
||||||
"mileage": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="mileage",
|
key="mileage",
|
||||||
translation_key="mileage",
|
translation_key="mileage",
|
||||||
unit_type=LENGTH,
|
unit_type=LENGTH,
|
||||||
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
||||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
"remaining_range_total": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="remaining_range_total",
|
key="remaining_range_total",
|
||||||
translation_key="remaining_range_total",
|
translation_key="remaining_range_total",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
@ -111,38 +118,42 @@ SENSOR_TYPES: dict[str, BMWSensorEntityDescription] = {
|
|||||||
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
"remaining_range_electric": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="remaining_range_electric",
|
key="remaining_range_electric",
|
||||||
translation_key="remaining_range_electric",
|
translation_key="remaining_range_electric",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
unit_type=LENGTH,
|
unit_type=LENGTH,
|
||||||
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_electric_drivetrain,
|
||||||
),
|
),
|
||||||
"remaining_range_fuel": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="remaining_range_fuel",
|
key="remaining_range_fuel",
|
||||||
translation_key="remaining_range_fuel",
|
translation_key="remaining_range_fuel",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
unit_type=LENGTH,
|
unit_type=LENGTH,
|
||||||
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
value=lambda x, hass: convert_and_round(x, hass.config.units.length, 2),
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_combustion_drivetrain,
|
||||||
),
|
),
|
||||||
"remaining_fuel": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="remaining_fuel",
|
key="remaining_fuel",
|
||||||
translation_key="remaining_fuel",
|
translation_key="remaining_fuel",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
unit_type=VOLUME,
|
unit_type=VOLUME,
|
||||||
value=lambda x, hass: convert_and_round(x, hass.config.units.volume, 2),
|
value=lambda x, hass: convert_and_round(x, hass.config.units.volume, 2),
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_combustion_drivetrain,
|
||||||
),
|
),
|
||||||
"remaining_fuel_percent": BMWSensorEntityDescription(
|
BMWSensorEntityDescription(
|
||||||
key="remaining_fuel_percent",
|
key="remaining_fuel_percent",
|
||||||
translation_key="remaining_fuel_percent",
|
translation_key="remaining_fuel_percent",
|
||||||
key_class="fuel_and_battery",
|
key_class="fuel_and_battery",
|
||||||
unit_type=PERCENTAGE,
|
unit_type=PERCENTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
is_available=lambda v: v.is_lsc_enabled and v.has_combustion_drivetrain,
|
||||||
),
|
),
|
||||||
}
|
]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
@ -153,16 +164,12 @@ async def async_setup_entry(
|
|||||||
"""Set up the MyBMW sensors from config entry."""
|
"""Set up the MyBMW sensors from config entry."""
|
||||||
coordinator: BMWDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator: BMWDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||||
|
|
||||||
entities: list[BMWSensor] = []
|
entities = [
|
||||||
|
|
||||||
for vehicle in coordinator.account.vehicles:
|
|
||||||
entities.extend(
|
|
||||||
[
|
|
||||||
BMWSensor(coordinator, vehicle, description)
|
BMWSensor(coordinator, vehicle, description)
|
||||||
for attribute_name in vehicle.available_attributes
|
for vehicle in coordinator.account.vehicles
|
||||||
if (description := SENSOR_TYPES.get(attribute_name))
|
for description in SENSOR_TYPES
|
||||||
|
if description.is_available(vehicle)
|
||||||
]
|
]
|
||||||
)
|
|
||||||
|
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
@ -1,34 +1,6 @@
|
|||||||
# serializer version: 1
|
# serializer version: 1
|
||||||
# name: test_entity_state_attrs
|
# name: test_entity_state_attrs
|
||||||
list([
|
list([
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'iX xDrive50 Remaining range total',
|
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.ix_xdrive50_remaining_range_total',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '340',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'iX xDrive50 Mileage',
|
|
||||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.ix_xdrive50_mileage',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '1121',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -54,6 +26,19 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': 'CHARGING',
|
'state': 'CHARGING',
|
||||||
}),
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'iX xDrive50 Charging target',
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.ix_xdrive50_charging_target',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '80',
|
||||||
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -69,6 +54,34 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '70',
|
'state': '70',
|
||||||
}),
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'iX xDrive50 Mileage',
|
||||||
|
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.ix_xdrive50_mileage',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '1121',
|
||||||
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'iX xDrive50 Remaining range total',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.ix_xdrive50_remaining_range_total',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '340',
|
||||||
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -83,47 +96,6 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '340',
|
'state': '340',
|
||||||
}),
|
}),
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'iX xDrive50 Charging target',
|
|
||||||
'unit_of_measurement': '%',
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.ix_xdrive50_charging_target',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '80',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'i4 eDrive40 Remaining range total',
|
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.i4_edrive40_remaining_range_total',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '472',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'i4 eDrive40 Mileage',
|
|
||||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.i4_edrive40_mileage',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '1121',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -149,6 +121,19 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': 'NOT_CHARGING',
|
'state': 'NOT_CHARGING',
|
||||||
}),
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'i4 eDrive40 Charging target',
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.i4_edrive40_charging_target',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '80',
|
||||||
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -164,6 +149,34 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '80',
|
'state': '80',
|
||||||
}),
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'i4 eDrive40 Mileage',
|
||||||
|
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.i4_edrive40_mileage',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '1121',
|
||||||
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'i4 eDrive40 Remaining range total',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.i4_edrive40_remaining_range_total',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '472',
|
||||||
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -181,15 +194,16 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
'friendly_name': 'i4 eDrive40 Charging target',
|
'friendly_name': 'M340i xDrive Mileage',
|
||||||
'unit_of_measurement': '%',
|
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
'entity_id': 'sensor.i4_edrive40_charging_target',
|
'entity_id': 'sensor.m340i_xdrive_mileage',
|
||||||
'last_changed': <ANY>,
|
'last_changed': <ANY>,
|
||||||
'last_reported': <ANY>,
|
'last_reported': <ANY>,
|
||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '80',
|
'state': '1121',
|
||||||
}),
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
@ -208,16 +222,16 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
'friendly_name': 'M340i xDrive Mileage',
|
'friendly_name': 'M340i xDrive Remaining range fuel',
|
||||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
'entity_id': 'sensor.m340i_xdrive_mileage',
|
'entity_id': 'sensor.m340i_xdrive_remaining_range_fuel',
|
||||||
'last_changed': <ANY>,
|
'last_changed': <ANY>,
|
||||||
'last_reported': <ANY>,
|
'last_reported': <ANY>,
|
||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '1121',
|
'state': '629',
|
||||||
}),
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
@ -233,20 +247,6 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '40',
|
'state': '40',
|
||||||
}),
|
}),
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'M340i xDrive Remaining range fuel',
|
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.m340i_xdrive_remaining_range_fuel',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '629',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -261,34 +261,6 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '80',
|
'state': '80',
|
||||||
}),
|
}),
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'i3 (+ REX) Remaining range total',
|
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.i3_rex_remaining_range_total',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '279',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'i3 (+ REX) Mileage',
|
|
||||||
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.i3_rex_mileage',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '137009',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -314,6 +286,19 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': 'WAITING_FOR_CHARGING',
|
'state': 'WAITING_FOR_CHARGING',
|
||||||
}),
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'i3 (+ REX) Charging target',
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.i3_rex_charging_target',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '100',
|
||||||
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -329,6 +314,34 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '82',
|
'state': '82',
|
||||||
}),
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'i3 (+ REX) Mileage',
|
||||||
|
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.i3_rex_mileage',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '137009',
|
||||||
|
}),
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
'friendly_name': 'i3 (+ REX) Remaining range total',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.i3_rex_remaining_range_total',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '279',
|
||||||
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
@ -346,15 +359,16 @@
|
|||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
'friendly_name': 'i3 (+ REX) Charging target',
|
'friendly_name': 'i3 (+ REX) Remaining range fuel',
|
||||||
'unit_of_measurement': '%',
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
'entity_id': 'sensor.i3_rex_charging_target',
|
'entity_id': 'sensor.i3_rex_remaining_range_fuel',
|
||||||
'last_changed': <ANY>,
|
'last_changed': <ANY>,
|
||||||
'last_reported': <ANY>,
|
'last_reported': <ANY>,
|
||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '100',
|
'state': '105',
|
||||||
}),
|
}),
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
@ -370,20 +384,6 @@
|
|||||||
'last_updated': <ANY>,
|
'last_updated': <ANY>,
|
||||||
'state': '6',
|
'state': '6',
|
||||||
}),
|
}),
|
||||||
StateSnapshot({
|
|
||||||
'attributes': ReadOnlyDict({
|
|
||||||
'attribution': 'Data provided by MyBMW',
|
|
||||||
'friendly_name': 'i3 (+ REX) Remaining range fuel',
|
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
|
||||||
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
|
||||||
}),
|
|
||||||
'context': <ANY>,
|
|
||||||
'entity_id': 'sensor.i3_rex_remaining_range_fuel',
|
|
||||||
'last_changed': <ANY>,
|
|
||||||
'last_reported': <ANY>,
|
|
||||||
'last_updated': <ANY>,
|
|
||||||
'state': '105',
|
|
||||||
}),
|
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
'attribution': 'Data provided by MyBMW',
|
'attribution': 'Data provided by MyBMW',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user