Skip to content

Commit

Permalink
feat: add last_updatedsensor for last API call (#125)
Browse files Browse the repository at this point in the history
* feat: add `last_updated`sensor for last API call

* linting and formatting
  • Loading branch information
firstof9 authored Jan 9, 2025
1 parent 4a79d68 commit 69d908a
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 16 deletions.
3 changes: 2 additions & 1 deletion custom_components/gasbuddy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import asyncio
import logging
from datetime import timedelta
from datetime import datetime, timedelta

from gasbuddy import GasBuddy # pylint: disable=import-self

Expand Down Expand Up @@ -182,4 +182,5 @@ async def _async_update_data(self) -> dict:
except Exception as exception:
raise UpdateFailed() from exception

self._data["last_updated"] = datetime.now()
return self._data
9 changes: 9 additions & 0 deletions custom_components/gasbuddy/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from typing import Final

from homeassistant.components.sensor import SensorDeviceClass

from .entity import GasBuddySensorEntityDescription

# config flow
Expand Down Expand Up @@ -37,6 +39,13 @@


SENSOR_TYPES: Final[dict[str, GasBuddySensorEntityDescription]] = {
"last_updated": GasBuddySensorEntityDescription(
name="Last Updated",
key="last_updated",
icon="mdi:update",
price=False,
device_class=SensorDeviceClass.TIMESTAMP,
),
"regular_gas": GasBuddySensorEntityDescription(
key="regular_gas",
name="Regular Gas",
Expand Down
1 change: 1 addition & 0 deletions custom_components/gasbuddy/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ class GasBuddySensorEntityDescription(SensorEntityDescription):
"""Class describing OpenEVSE select entities."""

cash: bool | None = None
price: bool | None = True
17 changes: 9 additions & 8 deletions custom_components/gasbuddy/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ def __init__(
self._data = coordinator.data
self.coordinator = coordinator
self._state = None
self._icon = sensor_description.icon
self._cash = sensor_description.cash
self._price = sensor_description.price

self._attr_icon = sensor_description.icon
self._attr_name = f"{self._config.data[CONF_NAME]} {self._name}"
self._attr_unique_id = f"{self._name}_{self._unique_id}"

Expand All @@ -80,6 +82,8 @@ def native_value(self) -> Any:
if data is None:
self._state = None
if self._type in data.keys():
if not self._price:
return data[self._type]
if self._cash and "cash_price" in data[self._type]:
if (
self.coordinator.data["unit_of_measure"] == "cents_per_liter"
Expand All @@ -105,16 +109,18 @@ def native_unit_of_measurement(self) -> Any:
"""Return the unit of measurement."""
uom = self.coordinator.data["unit_of_measure"]
currency = self.coordinator.data["currency"]
if self._config.data[CONF_UOM]:
if self._config.data[CONF_UOM] and self._price:
if uom is not None and currency is not None:
return f"{currency}/{UNIT_OF_MEASURE[uom]}"
elif currency is not None:
elif currency is not None and self._price:
return currency
return None

@property
def extra_state_attributes(self) -> Optional[dict]:
"""Return sesnsor attributes."""
if not self._price:
return None
credit = self.coordinator.data[self._type]["credit"]
attrs = {}
attrs[ATTR_ATTRIBUTION] = f"{credit} via GasBuddy"
Expand All @@ -135,11 +141,6 @@ def entity_picture(self) -> str | None:
return self.coordinator.data[ATTR_IMAGEURL]
return None

@property
def icon(self) -> str:
"""Return the icon."""
return self._icon

@property
def available(self) -> bool:
"""Return if entity is available."""
Expand Down
4 changes: 4 additions & 0 deletions tests/const.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""Constants for tests."""

from datetime import datetime, timezone

from custom_components.gasbuddy.const import (
CONF_GPS,
CONF_INTERVAL,
Expand Down Expand Up @@ -85,6 +87,7 @@
"cash_price": 3.13,
"last_updated": "2024-09-27T18:12:09.837Z",
},
"last_updated": datetime(2025, 1, 9, 16, 12, 51, tzinfo=timezone.utc),
}

COORDINATOR_DATA_CAD = {
Expand All @@ -106,4 +109,5 @@
"cash_price": 145.2,
"last_updated": "2023-12-10T17:31:01.856Z",
},
"last_updated": datetime(2025, 1, 9, 16, 12, 51, tzinfo=timezone.utc),
}
8 changes: 4 additions & 4 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ async def test_setup_and_unload_entry(hass, mock_gasbuddy):
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1

assert await hass.config_entries.async_unload(entries[0].entry_id)
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
assert len(hass.states.async_entity_ids(DOMAIN)) == 0

assert await hass.config_entries.async_remove(entries[0].entry_id)
Expand All @@ -44,13 +44,13 @@ async def test_setup_and_unload_entry_v1(hass, mock_gasbuddy):
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1

assert await hass.config_entries.async_unload(entries[0].entry_id)
await hass.async_block_till_done()
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
assert len(hass.states.async_entity_ids(DOMAIN)) == 0

assert await hass.config_entries.async_remove(entries[0].entry_id)
Expand Down
11 changes: 8 additions & 3 deletions tests/test_sensor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Test gasbuddy sensors."""

from datetime import datetime
import pytest
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE
Expand Down Expand Up @@ -27,7 +28,7 @@ async def test_sensors(hass, mock_gasbuddy, entity_registry: er.EntityRegistry):
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1

Expand Down Expand Up @@ -72,6 +73,10 @@ async def test_sensors(hass, mock_gasbuddy, entity_registry: er.EntityRegistry):
assert state
assert state.state == "3.35"

state = hass.states.get("sensor.gas_station_last_updated")
assert state
assert state.state == "2025-01-09T16:12:51+00:00"


async def test_sensors_no_uom(hass, mock_gasbuddy, entity_registry: er.EntityRegistry):
"""Test setup_entry."""
Expand All @@ -85,7 +90,7 @@ async def test_sensors_no_uom(hass, mock_gasbuddy, entity_registry: er.EntityReg
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1

Expand Down Expand Up @@ -140,7 +145,7 @@ async def test_sensors_cad(hass, mock_gasbuddy_cad, entity_registry: er.EntityRe
assert await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 3
assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 4
entries = hass.config_entries.async_entries(DOMAIN)
assert len(entries) == 1

Expand Down

0 comments on commit 69d908a

Please sign in to comment.