mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Add credit balance sensor to Teslemetry (#144365)
* Add credits * Credits string and icon * Add test * tests and fixes * Add units * Update homeassistant/components/teslemetry/sensor.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update snapshot with unit --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
9a06584a1d
commit
8ccedd4064
@ -241,7 +241,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TeslemetryConfigEntry) -
|
||||
)
|
||||
|
||||
# Setup Platforms
|
||||
entry.runtime_data = TeslemetryData(vehicles, energysites, scopes)
|
||||
entry.runtime_data = TeslemetryData(vehicles, energysites, scopes, stream)
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
if stream:
|
||||
|
@ -415,6 +415,9 @@
|
||||
"brick_voltage_min": {
|
||||
"default": "mdi:battery-low"
|
||||
},
|
||||
"credit_balance": {
|
||||
"default": "mdi:credit-card"
|
||||
},
|
||||
"cruise_follow_distance": {
|
||||
"default": "mdi:car-cruise-control"
|
||||
},
|
||||
|
@ -28,6 +28,7 @@ class TeslemetryData:
|
||||
vehicles: list[TeslemetryVehicleData]
|
||||
energysites: list[TeslemetryEnergyData]
|
||||
scopes: list[Scope]
|
||||
stream: TeslemetryStream
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -6,7 +6,7 @@ from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from teslemetry_stream import TeslemetryStreamVehicle
|
||||
from teslemetry_stream import TeslemetryStream, TeslemetryStreamVehicle
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
RestoreSensor,
|
||||
@ -45,7 +45,7 @@ from .entity import (
|
||||
TeslemetryVehicleStreamEntity,
|
||||
TeslemetryWallConnectorEntity,
|
||||
)
|
||||
from .models import TeslemetryEnergyData, TeslemetryVehicleData
|
||||
from .models import TeslemetryData, TeslemetryEnergyData, TeslemetryVehicleData
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
@ -1618,6 +1618,12 @@ async def async_setup_entry(
|
||||
if energysite.history_coordinator is not None
|
||||
)
|
||||
|
||||
entities.append(
|
||||
TeslemetryCreditBalanceSensor(
|
||||
entry.unique_id or entry.entry_id, entry.runtime_data
|
||||
)
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
@ -1825,3 +1831,33 @@ class TeslemetryEnergyHistorySensorEntity(TeslemetryEnergyHistoryEntity, SensorE
|
||||
def _async_update_attrs(self) -> None:
|
||||
"""Update the attributes of the sensor."""
|
||||
self._attr_native_value = self._value
|
||||
|
||||
|
||||
class TeslemetryCreditBalanceSensor(RestoreSensor):
|
||||
"""Entity for Teslemetry Credit balance."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
stream: TeslemetryStream
|
||||
_attr_state_class = SensorStateClass.MEASUREMENT
|
||||
_attr_suggested_display_precision = 0
|
||||
|
||||
def __init__(self, uid: str, data: TeslemetryData) -> None:
|
||||
"""Initialize common aspects of a Teslemetry entity."""
|
||||
|
||||
self._attr_translation_key = "credit_balance"
|
||||
self._attr_unique_id = f"{uid}_credit_balance"
|
||||
self.stream = data.stream
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Handle entity which will be added."""
|
||||
await super().async_added_to_hass()
|
||||
|
||||
if (sensor_data := await self.async_get_last_sensor_data()) is not None:
|
||||
self._attr_native_value = sensor_data.native_value
|
||||
|
||||
self.async_on_remove(self.stream.listen_Balance(self._async_update))
|
||||
|
||||
def _async_update(self, value: int) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._attr_native_value = value
|
||||
self.async_write_ha_state()
|
||||
|
@ -490,6 +490,10 @@
|
||||
"climate_state_passenger_temp_setting": {
|
||||
"name": "Passenger temperature setting"
|
||||
},
|
||||
"credit_balance": {
|
||||
"name": "Teslemetry credits",
|
||||
"unit_of_measurement": "credits"
|
||||
},
|
||||
"drive_state_active_route_destination": {
|
||||
"name": "Destination"
|
||||
},
|
||||
|
@ -2424,6 +2424,75 @@
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.teslemetry_credits-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.teslemetry_credits',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Teslemetry credits',
|
||||
'platform': 'teslemetry',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'credit_balance',
|
||||
'unique_id': 'abc-123_credit_balance',
|
||||
'unit_of_measurement': 'credits',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.teslemetry_credits-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Teslemetry credits',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'credits',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.teslemetry_credits',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.teslemetry_credits-statealt]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Teslemetry credits',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': 'credits',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.teslemetry_credits',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'unknown',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[sensor.test_battery_level-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@ -5054,6 +5123,9 @@
|
||||
'state': 'disconnected',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors_streaming[sensor.teslemetry_credits-state]
|
||||
'1980'
|
||||
# ---
|
||||
# name: test_sensors_streaming[sensor.test_battery_level-state]
|
||||
'90'
|
||||
# ---
|
||||
|
@ -73,6 +73,12 @@ async def test_sensors_streaming(
|
||||
Signal.TIME_TO_FULL_CHARGE: 0.166666667,
|
||||
Signal.MINUTES_TO_ARRIVAL: None,
|
||||
},
|
||||
"credits": {
|
||||
"type": "wake_up",
|
||||
"cost": 20,
|
||||
"name": "wake_up",
|
||||
"balance": 1980,
|
||||
},
|
||||
"createdAt": "2024-10-04T10:45:17.537Z",
|
||||
}
|
||||
)
|
||||
@ -91,6 +97,7 @@ async def test_sensors_streaming(
|
||||
"sensor.test_charge_cable",
|
||||
"sensor.test_time_to_full_charge",
|
||||
"sensor.test_time_to_arrival",
|
||||
"sensor.teslemetry_credits",
|
||||
):
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == snapshot(name=f"{entity_id}-state")
|
||||
|
Loading…
x
Reference in New Issue
Block a user