diff --git a/custom_components/tesla_custom/sensor.py b/custom_components/tesla_custom/sensor.py index 4d212d8f..f8f097da 100644 --- a/custom_components/tesla_custom/sensor.py +++ b/custom_components/tesla_custom/sensor.py @@ -1,4 +1,8 @@ """Support for the Tesla sensors.""" + +from datetime import datetime, timedelta +from typing import Optional + from teslajsonpy.car import TeslaCar from teslajsonpy.const import RESOURCE_TYPE_SOLAR, RESOURCE_TYPE_BATTERY from teslajsonpy.energy import EnergySite, PowerwallSite @@ -20,20 +24,16 @@ PRESSURE_PSI, SPEED_MILES_PER_HOUR, TEMP_CELSIUS, - TIME_HOURS, ) from homeassistant.core import HomeAssistant from homeassistant.helpers.icon import icon_for_battery_level -from homeassistant.util.unit_conversion import DistanceConverter, PressureConverter +from homeassistant.util.unit_conversion import DistanceConverter from homeassistant.util import dt from . import TeslaDataUpdateCoordinator from .base import TeslaCarEntity, TeslaEnergyEntity from .const import DISTANCE_UNITS_KM_HR, DOMAIN -from datetime import datetime, timedelta -from typing import Optional - SOLAR_SITE_SENSORS = ["solar power", "grid power", "load power"] BATTERY_SITE_SENSORS = SOLAR_SITE_SENSORS + ["battery power"] @@ -501,7 +501,6 @@ def __init__( super().__init__(hass, car, coordinator) self.type = "time charge complete" self._attr_device_class = SensorDeviceClass.TIMESTAMP - self._attr_state_class = SensorStateClass.MEASUREMENT self._attr_icon = "mdi:timer-plus" self._value: Optional[datetime] = None @@ -574,7 +573,6 @@ def __init__( super().__init__(hass, car, coordinator) self.type = "arrival time" self._attr_device_class = SensorDeviceClass.TIMESTAMP - self._attr_state_class = SensorStateClass.MEASUREMENT self._attr_icon = "mdi:timer-sand" self._datetime_value: Optional[datetime] = None self._last_known_value: Optional[int] = None @@ -588,14 +586,13 @@ def native_value(self) -> Optional[datetime]: else: min_duration = round(float(self._car.active_route_minutes_to_arrival), 2) + utcnow = dt.utcnow() if self._last_known_value != min_duration: self._last_known_value = min_duration - self._last_update_time = dt.utcnow() + self._last_update_time = utcnow new_value = ( - dt.utcnow() - + timedelta(minutes=min_duration) - - (dt.utcnow() - self._last_update_time) + utcnow + timedelta(minutes=min_duration) - (utcnow - self._last_update_time) ) if ( self._datetime_value is None diff --git a/tests/test_sensor.py b/tests/test_sensor.py index 85ff1281..eebadf97 100644 --- a/tests/test_sensor.py +++ b/tests/test_sensor.py @@ -1,5 +1,9 @@ """Tests for the Tesla sensor device.""" +from datetime import datetime, timedelta, timezone + +from pytest import MonkeyPatch + from homeassistant.components.sensor import ( DOMAIN as SENSOR_DOMAIN, SensorDeviceClass, @@ -23,6 +27,7 @@ ) from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er +from homeassistant.util import dt from homeassistant.util.unit_conversion import ( DistanceConverter, SpeedConverter, @@ -33,7 +38,6 @@ from .mock_data import car as car_mock_data from .mock_data import energysite as energysite_mock_data -from datetime import datetime, timedelta ATTR_STATE_CLASS = "state_class" @@ -238,12 +242,16 @@ async def test_charger_rate_value(hass: HomeAssistant) -> None: ) -async def test_time_charge_complete_charging(hass: HomeAssistant) -> None: +async def test_time_charge_complete_charging( + hass: HomeAssistant, monkeypatch: MonkeyPatch +) -> None: """Tests time charge complete is the correct value.""" + mock_now = datetime(2022, 12, 1, 2, 3, 4, 0, timezone.utc) + monkeypatch.setattr(dt, "utcnow", lambda: mock_now) await setup_platform(hass, SENSOR_DOMAIN) state = hass.states.get("sensor.my_model_s_time_charge_complete") - charge_complete = datetime.utcnow() + timedelta( + charge_complete = mock_now + timedelta( hours=float(car_mock_data.VEHICLE_DATA["charge_state"]["time_to_full_charge"]) ) charge_complete_str = datetime.strftime(charge_complete, "%Y-%m-%dT%H:%M:%S+00:00") @@ -251,7 +259,7 @@ async def test_time_charge_complete_charging(hass: HomeAssistant) -> None: assert state.state == charge_complete_str assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.TIMESTAMP - assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT + assert state.attributes.get(ATTR_STATE_CLASS) is None async def test_time_charge_completed(hass: HomeAssistant) -> None: @@ -535,15 +543,17 @@ async def test_tpms_pressure_none(hass: HomeAssistant) -> None: assert state_fl.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT assert state_fl.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == PRESSURE_PSI - assert state_fl.attributes.get("tpms_last_seen_pressure_timestamp") == None + assert state_fl.attributes.get("tpms_last_seen_pressure_timestamp") is None -async def test_arrival_time(hass: HomeAssistant) -> None: +async def test_arrival_time(hass: HomeAssistant, monkeypatch: MonkeyPatch) -> None: """Tests arrival time is getting the correct value.""" + mock_now = datetime(2022, 12, 1, 2, 3, 4, 0, timezone.utc) + monkeypatch.setattr(dt, "utcnow", lambda: mock_now) await setup_platform(hass, SENSOR_DOMAIN) state = hass.states.get("sensor.my_model_s_arrival_time") - arrival_time = datetime.utcnow() + timedelta( + arrival_time = mock_now + timedelta( minutes=round( float( car_mock_data.VEHICLE_DATA["drive_state"][ @@ -558,7 +568,7 @@ async def test_arrival_time(hass: HomeAssistant) -> None: assert state.state == arrival_time_str assert state.attributes.get(ATTR_DEVICE_CLASS) == SensorDeviceClass.TIMESTAMP - assert state.attributes.get(ATTR_STATE_CLASS) == SensorStateClass.MEASUREMENT + assert state.attributes.get(ATTR_STATE_CLASS) is None assert ( state.attributes.get("Energy at arrival") == car_mock_data.VEHICLE_DATA["drive_state"]["active_route_energy_at_arrival"]