This repository has been archived by the owner on Mar 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
92aabbb
commit 5bb85dc
Showing
3 changed files
with
179 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,117 @@ | ||
"""The Barry App integration.""" | ||
import logging | ||
from random import randint | ||
from datetime import datetime, timedelta | ||
from pytz import timezone | ||
|
||
from pybarry import Barry | ||
|
||
import voluptuous as vol | ||
|
||
from homeassistant import config_entries | ||
from homeassistant.const import CONF_ACCESS_TOKEN | ||
|
||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import HomeAssistant | ||
from homeassistant.core import Config,HomeAssistant | ||
from homeassistant.helpers.dispatcher import async_dispatcher_send | ||
from homeassistant.helpers.event import async_call_later, async_track_time_change | ||
|
||
from .const import DOMAIN, PRICE_CODE | ||
from .events import async_track_time_change_in_tz | ||
|
||
PLATFORMS = ["sensor"] | ||
EVENT_NEW_DATA = "barry_update" | ||
RANDOM_MINUTE = randint(0, 10) | ||
RANDOM_SECOND = randint(0, 59) | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA) | ||
|
||
async def async_setup(hass, config): | ||
"""Set up the Barry component.""" | ||
class BarryData: | ||
def __init__(self, hass: HomeAssistant): | ||
self._hass = hass | ||
self.listeners = [] | ||
self.barry_connection = None | ||
|
||
if DOMAIN not in config: | ||
return True | ||
async def _dry_setup(hass, entry) -> bool: | ||
"""Setup""" | ||
_LOGGER.debug("Running _dry_setup") | ||
|
||
hass.async_create_task( | ||
hass.config_entries.flow.async_init( | ||
DOMAIN, | ||
context={"source": config_entries.SOURCE_IMPORT}, | ||
data=config[DOMAIN], | ||
if DOMAIN not in hass.data: | ||
_LOGGER.debug("Setting up integration: %s", entry) | ||
api = BarryData(hass) | ||
|
||
api.barry_connection = Barry( | ||
access_token=entry.data[CONF_ACCESS_TOKEN], | ||
) | ||
) | ||
|
||
hass.data[DOMAIN] = api | ||
|
||
async def new_hr(n): | ||
"""Callback to tell the sensors to update on a new hour.""" | ||
_LOGGER.debug("Called new_hr callback") | ||
async_dispatcher_send(hass, EVENT_NEW_DATA) | ||
|
||
async def new_data_cb(n): | ||
"""Callback to fetch new data for tomorrows prices at 1300ish CET | ||
and notify any sensors, about the new data | ||
""" | ||
_LOGGER.debug("Called new_data_cb") | ||
async_dispatcher_send(hass, EVENT_NEW_DATA) | ||
|
||
cb_update_tomorrow = async_track_time_change_in_tz( | ||
hass, | ||
new_data_cb, | ||
hour=13, | ||
minute=RANDOM_MINUTE, | ||
second=RANDOM_SECOND, | ||
tz=timezone("Europe/Stockholm"), | ||
) | ||
|
||
cb_new_hr = async_track_time_change( | ||
hass, new_hr, minute=0, second=0 | ||
) | ||
|
||
api.listeners.append(cb_update_tomorrow) | ||
api.listeners.append(cb_new_hr) | ||
|
||
return True | ||
|
||
|
||
async def async_setup_entry(hass, entry): | ||
async def async_setup(hass: HomeAssistant, config: ConfigEntry): | ||
# """Set up the Barry component.""" | ||
# #hass.data[DOMAIN] = {} | ||
# #return await _dry_setup(hass, entry.data) | ||
return True | ||
|
||
|
||
async def async_setup_entry(hass, entry) -> bool: | ||
"""Set up a config entry.""" | ||
res = await _dry_setup(hass, entry) | ||
|
||
barry_connection = Barry( | ||
access_token=entry.data[CONF_ACCESS_TOKEN], | ||
hass.async_create_task( | ||
hass.config_entries.async_forward_entry_setup(entry, "sensor") | ||
) | ||
hass.data[DOMAIN] = barry_connection | ||
hass.data[PRICE_CODE] = entry.data[PRICE_CODE] | ||
|
||
hass.config_entries.async_setup_platforms(entry, PLATFORMS) | ||
|
||
return True | ||
return res | ||
|
||
|
||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
"""Unload a config entry.""" | ||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) | ||
unload_ok = await hass.config_entries.async_forward_entry_unload(entry, "sensor") | ||
|
||
if unload_ok: | ||
for unsub in hass.data[DOMAIN].listeners: | ||
unsub() | ||
hass.data.pop(DOMAIN) | ||
|
||
return True | ||
|
||
return False | ||
|
||
|
||
async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: | ||
"""Reload config entry.""" | ||
await async_unload_entry(hass, entry) | ||
await async_setup_entry(hass, entry) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
from datetime import datetime, timedelta | ||
from typing import Any, Callable, Optional | ||
|
||
from homeassistant.const import ATTR_NOW, EVENT_TIME_CHANGED | ||
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback | ||
from homeassistant.loader import bind_hass | ||
from homeassistant.util import dt as dt_util | ||
from pytz import timezone | ||
|
||
|
||
def stock(d): | ||
"""convert datetime to Copenhagen time.""" | ||
return d.astimezone(timezone("Europe/Copenhagen")) | ||
|
||
|
||
@callback | ||
@bind_hass | ||
def async_track_utc_time_change( | ||
hass: HomeAssistant, | ||
action: Callable[..., None], | ||
hour: Optional[Any] = None, | ||
minute: Optional[Any] = None, | ||
second: Optional[Any] = None, | ||
tz: Optional[Any] = None, | ||
) -> CALLBACK_TYPE: | ||
"""Add a listener that will fire if time matches a pattern.""" | ||
# We do not have to wrap the function with time pattern matching logic | ||
# if no pattern given | ||
if all(val is None for val in (hour, minute, second)): | ||
|
||
@callback | ||
def time_change_listener(event: Event) -> None: | ||
"""Fire every time event that comes in.""" | ||
hass.async_run_job(action, event.data[ATTR_NOW]) | ||
|
||
return hass.bus.async_listen(EVENT_TIME_CHANGED, time_change_listener) | ||
|
||
matching_seconds = dt_util.parse_time_expression(second, 0, 59) | ||
matching_minutes = dt_util.parse_time_expression(minute, 0, 59) | ||
matching_hours = dt_util.parse_time_expression(hour, 0, 23) | ||
|
||
next_time = None | ||
|
||
def calculate_next(now: datetime) -> None: | ||
"""Calculate and set the next time the trigger should fire.""" | ||
nonlocal next_time | ||
|
||
localized_now = now.astimezone(tz) if tz else now | ||
next_time = dt_util.find_next_time_expression_time( | ||
localized_now, matching_seconds, matching_minutes, matching_hours | ||
) | ||
|
||
# Make sure rolling back the clock doesn't prevent the timer from | ||
# triggering. | ||
last_now: Optional[datetime] = None | ||
|
||
@callback | ||
def pattern_time_change_listener(event: Event) -> None: | ||
"""Listen for matching time_changed events.""" | ||
nonlocal next_time, last_now | ||
|
||
now = event.data[ATTR_NOW] | ||
|
||
if last_now is None or now < last_now: | ||
# Time rolled back or next time not yet calculated | ||
calculate_next(now) | ||
|
||
last_now = now | ||
|
||
if next_time <= now: | ||
hass.async_run_job(action, now.astimezone(tz) if tz else now) | ||
calculate_next(now + timedelta(seconds=1)) | ||
|
||
# We can't use async_track_point_in_utc_time here because it would | ||
# break in the case that the system time abruptly jumps backwards. | ||
# Our custom last_now logic takes care of resolving that scenario. | ||
return hass.bus.async_listen(EVENT_TIME_CHANGED, pattern_time_change_listener) | ||
|
||
|
||
@callback | ||
@bind_hass | ||
def async_track_time_change_in_tz( | ||
hass: HomeAssistant, | ||
action: Callable[..., None], | ||
hour: Optional[Any] = None, | ||
minute: Optional[Any] = None, | ||
second: Optional[Any] = None, | ||
tz: Optional[Any] = None, | ||
) -> CALLBACK_TYPE: | ||
"""Add a listener that will fire if UTC time matches a pattern.""" | ||
return async_track_utc_time_change(hass, action, hour, minute, second, tz) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters