Skip to content

Commit

Permalink
Add next draw sensor (#11)
Browse files Browse the repository at this point in the history
* Add next draw sensor

* Fix lint
  • Loading branch information
inverse authored Jan 6, 2025
1 parent ea48755 commit 8c2318a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 12 deletions.
32 changes: 26 additions & 6 deletions custom_components/premium_bond_checker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant

from .const import CONF_HOLDER_NUMBER, DOMAIN
from .coordinator import PremiumBondCheckerData
from .const import (
CONF_HOLDER_NUMBER,
COORDINATOR_CHECKER,
COORDINATOR_NEXT_DRAW,
DOMAIN,
)
from .coordinator import PremiumBondCheckerData, PremiumBondNextDrawData

_LOGGER = logging.getLogger(__name__)

Expand All @@ -21,11 +26,15 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
"Setting up entry for holder number: %s", config_entry.data[CONF_HOLDER_NUMBER]
)

coordinator = await create_and_update_coordinator(hass, config_entry)

config_entry.async_on_unload(config_entry.add_update_listener(update_listener))
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][config_entry.entry_id] = coordinator
hass.data[DOMAIN].setdefault(config_entry.entry_id, {})
hass.data[DOMAIN][config_entry.entry_id][
COORDINATOR_CHECKER
] = await create_and_update_checker_coordinator(hass, config_entry)
hass.data[DOMAIN][config_entry.entry_id][
COORDINATOR_NEXT_DRAW
] = await create_and_update_next_draw_coordinator(hass, config_entry)

await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)

Expand All @@ -41,7 +50,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return unload_ok


async def create_and_update_coordinator(
async def create_and_update_checker_coordinator(
hass, entry: ConfigEntry
) -> PremiumBondCheckerData:
"""Create and update a Premium Bond Checker coordinator."""
Expand All @@ -58,6 +67,17 @@ async def create_and_update_coordinator(
return coordinator


async def create_and_update_next_draw_coordinator(
hass, entry: ConfigEntry
) -> PremiumBondNextDrawData:
"""Create and update a Premium Bond Next Draw coordinator."""
coordinator = PremiumBondNextDrawData(hass)
_LOGGER.debug("Requesting instance update")
await coordinator.async_config_entry_first_refresh()

return coordinator


async def update_listener(hass, config_entry):
"""Handle options update."""

Expand Down
3 changes: 3 additions & 0 deletions custom_components/premium_bond_checker/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

CONF_HOLDER_NUMBER = "holder_number"

COORDINATOR_CHECKER = "checker"
COORDINATOR_NEXT_DRAW = "next_draw"


ATTR_HEADER = "header"
ATTR_TAGLINE = "tagline"
Expand Down
24 changes: 24 additions & 0 deletions custom_components/premium_bond_checker/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,30 @@
MIN_TIME_BETWEEN_UPDATES = timedelta(days=1)


class PremiumBondNextDrawData(DataUpdateCoordinator):
"""Get the latest data and update the states."""

def __init__(self, hass: HomeAssistant):
"""Init the premium bond checker data object."""

self.hass = hass
self.client = Client()

super().__init__(
hass, _LOGGER, name=DOMAIN, update_interval=MIN_TIME_BETWEEN_UPDATES
)

async def _async_update_data(self):
"""Get the latest data."""
_LOGGER.debug("Allowing instance update")
try:
return await self.hass.async_add_executor_job(
self.client.next_draw,
)
except Exception as err:
_LOGGER.warning("Experienced unexpected error while updating: %s", err)


class PremiumBondCheckerData(DataUpdateCoordinator):
"""Get the latest data and update the states."""

Expand Down
2 changes: 1 addition & 1 deletion custom_components/premium_bond_checker/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"domain": "premium_bond_checker",
"iot_class": "cloud_polling",
"name": "Premium Bond Checker",
"requirements": ["premium-bond-checker==0.3.1"],
"requirements": ["premium-bond-checker==0.4.0"],
"version": "0.1.0"
}
52 changes: 48 additions & 4 deletions custom_components/premium_bond_checker/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
from typing import Any

from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from premium_bond_checker.client import Result

from . import COORDINATOR_CHECKER, COORDINATOR_NEXT_DRAW
from .const import (
ATTR_HEADER,
ATTR_TAGLINE,
Expand All @@ -29,14 +31,27 @@ async def async_setup_entry(
) -> None:
"""Set up Premium Bond Checker sensor platform."""

coordinator = hass.data[DOMAIN][config_entry.entry_id]
entities: list[BinarySensorEntity] = []
checker_coordinator = hass.data[DOMAIN][config_entry.entry_id][COORDINATOR_CHECKER]

next_draw_coordinator = hass.data[DOMAIN][config_entry.entry_id][
COORDINATOR_NEXT_DRAW
]

entities = []

_LOGGER.debug("Adding sensor for next draw")
entities.append(
PremiumBondNextDrawSensor(
next_draw_coordinator,
config_entry.data[CONF_HOLDER_NUMBER],
)
)

for period_key, bond_period in BOND_PERIODS.items():
_LOGGER.debug("Adding sensor for %s", period_key)
entities.append(
PremiumBondCheckerSensor(
coordinator,
checker_coordinator,
config_entry.data[CONF_HOLDER_NUMBER],
period_key,
bond_period,
Expand All @@ -52,7 +67,6 @@ def __init__(
):
"""Initialize the sensor."""
super().__init__(coordinator)
self._data = coordinator
self._bond_period = bond_period
self._name = (
f"Premium Bond Checker {holder_number} {BOND_PERIODS_TO_NAME[period_key]}"
Expand Down Expand Up @@ -86,3 +100,33 @@ def extra_state_attributes(self) -> dict[str, Any]:
ATTR_HEADER: self.data.header,
ATTR_TAGLINE: self.data.tagline,
}


class PremiumBondNextDrawSensor(CoordinatorEntity, SensorEntity):
def __init__(self, coordinator, holder_number: str):
"""Initialize the sensor."""
super().__init__(coordinator)
self._name = f"Premium Bond Checker {holder_number} Next Draw"
self._id = f"premium_bond_checker-{holder_number}-next-draw"

@property
def name(self) -> str:
"""Return the name of the sensor."""
return self._name

@property
def unique_id(self) -> str:
return self._id

@property
def native_value(self):
"""Return the state of the sensor."""

_LOGGER.debug(f"Got next draw value of {self.coordinator.data}")

return self.coordinator.data

@property
def device_class(self) -> SensorDeviceClass | str | None:
"""Return the device class of the sensor."""
return SensorDeviceClass.DATE
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ pytest-cov
pytest-homeassistant-custom-component
pytest-asyncio
# From manifest
premium-bond-checker==0.3.1
premium-bond-checker==0.4.0

0 comments on commit 8c2318a

Please sign in to comment.