-
-
Notifications
You must be signed in to change notification settings - Fork 36.3k
Add Islamic Prayer Times config flow #31590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
MartinHjelmare
merged 21 commits into
home-assistant:dev
from
engrbm87:islamic-prayer-config-flow
Apr 20, 2020
Merged
Changes from 12 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
b41c566
Add Islamic Prayer Times config_flow
engrbm87 211b60a
Add Islamic Prayer Times config_flow
engrbm87 a98ee58
Merge branch 'islamic-prayer-config-flow' of https://github.com/engrb…
engrbm87 4fd2cea
handle options update and fix tests
engrbm87 87460d0
fix sensor update handling
engrbm87 8336df4
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
engrbm87 0e544e5
fix pylint
engrbm87 d412176
fix scheduled update and add test
engrbm87 8f9d01b
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
engrbm87 2a61a7d
update test_init
engrbm87 d5e6dfb
update flow options to show drop list
engrbm87 da7f34c
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
engrbm87 33e757e
Merge branch 'dev' into islamic-prayer-config-flow
engrbm87 25547a3
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
engrbm87 ee453f6
clean up code
engrbm87 3c75168
Merge branch 'islamic-prayer-config-flow' of https://github.com/engrb…
engrbm87 92ca24c
async scheduling and revert state to timestamp
engrbm87 d2b9782
fix update retry method
engrbm87 a1c57a9
Merge branch 'dev' of https://github.com/home-assistant/home-assistan…
engrbm87 d8d3df0
update strings
engrbm87 f3dc053
keep title as root key
engrbm87 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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
24 changes: 24 additions & 0 deletions
24
homeassistant/components/islamic_prayer_times/.translations/en.json
This file contains hidden or 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,24 @@ | ||
| { | ||
| "config": { | ||
| "title": "Islamic Prayer Times", | ||
| "step": { | ||
| "user": { | ||
| "title": "Set up Islamic Prayer Times", | ||
| "description": "Are you sure you want to set up Islamic Prayer Times?" | ||
| } | ||
| }, | ||
| "abort": { | ||
| "one_instance_allowed": "Only a single instance is necessary." | ||
| } | ||
| }, | ||
| "options": { | ||
| "title": "Configure options for Islamic Prayer Times", | ||
| "step": { | ||
| "init": { | ||
| "data": { | ||
| "calculation_method": "Prayer calculation method" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
205 changes: 205 additions & 0 deletions
205
homeassistant/components/islamic_prayer_times/__init__.py
This file contains hidden or 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 +1,206 @@ | ||
| """The islamic_prayer_times component.""" | ||
| from datetime import datetime, timedelta | ||
| import logging | ||
|
|
||
| from prayer_times_calculator import PrayerTimesCalculator, exceptions | ||
| import voluptuous as vol | ||
|
|
||
| from homeassistant.config_entries import SOURCE_IMPORT | ||
| from homeassistant.exceptions import ConfigEntryNotReady | ||
| from homeassistant.helpers.dispatcher import async_dispatcher_send | ||
| from homeassistant.helpers.event import async_track_point_in_time | ||
| import homeassistant.util.dt as dt_util | ||
|
|
||
| from .const import ( | ||
| CALC_METHODS, | ||
| CONF_CALC_METHOD, | ||
| DATA_UPDATED, | ||
| DEFAULT_CALC_METHOD, | ||
| DOMAIN, | ||
| ) | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| CONFIG_SCHEMA = vol.Schema( | ||
| { | ||
| DOMAIN: { | ||
| vol.Optional(CONF_CALC_METHOD, default=DEFAULT_CALC_METHOD): vol.In( | ||
| CALC_METHODS | ||
| ), | ||
| } | ||
| }, | ||
| extra=vol.ALLOW_EXTRA, | ||
| ) | ||
|
|
||
|
|
||
| async def async_setup(hass, config): | ||
| """Import the Islamic Prayer component from config.""" | ||
| if DOMAIN in config: | ||
| hass.async_create_task( | ||
| hass.config_entries.flow.async_init( | ||
| DOMAIN, context={"source": SOURCE_IMPORT}, data=config[DOMAIN] | ||
| ) | ||
| ) | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| async def async_setup_entry(hass, config_entry): | ||
| """Set up the Islamic Prayer Component.""" | ||
| client = IslamicPrayerClient(hass, config_entry) | ||
|
|
||
| if not await client.async_setup(): | ||
| return False | ||
|
|
||
| hass.data.setdefault(DOMAIN, {}) | ||
| hass.data[DOMAIN] = client | ||
| return True | ||
|
|
||
|
|
||
| async def async_unload_entry(hass, config_entry): | ||
| """Unload Transmission Entry from config_entry.""" | ||
|
|
||
| await hass.config_entries.async_forward_entry_unload(config_entry, "sensor") | ||
|
|
||
| hass.data.pop(DOMAIN) | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| class IslamicPrayerClient: | ||
| """Islamic Prayer Client Object.""" | ||
|
|
||
| def __init__(self, hass, config_entry): | ||
| """Initialize the Islamic Prayer client.""" | ||
| self.hass = hass | ||
| self.config_entry = config_entry | ||
| self.prayer_times_info = None | ||
| self.available = None | ||
|
|
||
| async def get_new_prayer_times(self): | ||
| """Fetch prayer times for today.""" | ||
|
|
||
| calc = PrayerTimesCalculator( | ||
| latitude=self.hass.config.latitude, | ||
| longitude=self.hass.config.longitude, | ||
| calculation_method=self.config_entry.options[CONF_CALC_METHOD], | ||
| date=str(dt_util.now().date()), | ||
| ) | ||
| self.prayer_times_info = calc.fetch_prayer_times() | ||
engrbm87 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| async def schedule_future_update(self): | ||
| """Schedule future update for sensors. | ||
| Midnight is a calculated time. The specifics of the calculation | ||
| depends on the method of the prayer time calculation. This calculated | ||
| midnight is the time at which the time to pray the Isha prayers have | ||
| expired. | ||
| Calculated Midnight: The Islamic midnight. | ||
| Traditional Midnight: 12:00AM | ||
| Update logic for prayer times: | ||
| If the Calculated Midnight is before the traditional midnight then wait | ||
| until the traditional midnight to run the update. This way the day | ||
| will have changed over and we don't need to do any fancy calculations. | ||
| If the Calculated Midnight is after the traditional midnight, then wait | ||
| until after the calculated Midnight. We don't want to update the prayer | ||
| times too early or else the timings might be incorrect. | ||
| Example: | ||
| calculated midnight = 11:23PM (before traditional midnight) | ||
| Update time: 12:00AM | ||
| calculated midnight = 1:35AM (after traditional midnight) | ||
| update time: 1:36AM. | ||
| """ | ||
| _LOGGER.debug("Scheduling next update for Islamic prayer times") | ||
|
|
||
| midnight_time = self.prayer_times_info["Midnight"] | ||
| now = dt_util.as_local(dt_util.now()) | ||
| today = now.date() | ||
|
|
||
| midnight_dt_str = "{}::{}".format(str(today), midnight_time) | ||
| midnight_dt = datetime.strptime(midnight_dt_str, "%Y-%m-%d::%H:%M") | ||
|
|
||
| if now > dt_util.as_local(midnight_dt): | ||
| _LOGGER.debug( | ||
| "Midnight is after day the changes so schedule update " | ||
| "for after Midnight the next day" | ||
| ) | ||
|
|
||
| next_update_at = midnight_dt + timedelta(days=1, minutes=1) | ||
| else: | ||
| _LOGGER.debug( | ||
| "Midnight is before the day changes so schedule update for the " | ||
| "next start of day" | ||
| ) | ||
|
|
||
| tomorrow = now + timedelta(days=1) | ||
| next_update_at = dt_util.start_of_local_day(tomorrow) | ||
|
|
||
| _LOGGER.debug("Next update scheduled for: %s", str(next_update_at)) | ||
|
|
||
| async_track_point_in_time(self.hass, self.async_update, next_update_at) | ||
|
|
||
| async def async_update(self, *_): | ||
| """Update sensors with new prayer times.""" | ||
| try: | ||
| await self.get_new_prayer_times() | ||
| await self.schedule_future_update() | ||
| self.available = True | ||
| _LOGGER.debug("New prayer times retrieved. Updating sensors.") | ||
|
|
||
| except exceptions.InvalidResponseError: | ||
engrbm87 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| self.available = False | ||
|
|
||
| async_dispatcher_send(self.hass, DATA_UPDATED) | ||
|
|
||
| async def async_setup(self): | ||
| """Set up the Islamic prayer client.""" | ||
|
|
||
| self.add_options() | ||
|
|
||
| try: | ||
| await self.get_new_prayer_times() | ||
| except exceptions.InvalidResponseError: | ||
| raise ConfigEntryNotReady | ||
|
|
||
| await self.async_update() | ||
| self.config_entry.add_update_listener(self.async_options_updated) | ||
|
|
||
| self.hass.async_create_task( | ||
| self.hass.config_entries.async_forward_entry_setup( | ||
| self.config_entry, "sensor" | ||
| ) | ||
| ) | ||
|
|
||
| return True | ||
|
|
||
| def add_options(self): | ||
engrbm87 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """Add options for entry.""" | ||
| if not self.config_entry.options: | ||
| calc_method = self.config_entry.data.get( | ||
| CONF_CALC_METHOD, DEFAULT_CALC_METHOD | ||
| ) | ||
|
|
||
| self.hass.config_entries.async_update_entry( | ||
| self.config_entry, options={CONF_CALC_METHOD: calc_method} | ||
| ) | ||
|
|
||
| @staticmethod | ||
| def get_prayer_time_as_dt(prayer_time): | ||
| """Create a datetime object for the respective prayer time.""" | ||
| today = dt_util.now().date() | ||
| date_time_str = "{} {}".format(str(today), prayer_time) | ||
| pt_dt = dt_util.parse_datetime(date_time_str) | ||
| return pt_dt | ||
|
|
||
| @staticmethod | ||
| async def async_options_updated(hass, entry): | ||
| """Triggered by config entry options updates.""" | ||
| await hass.data[DOMAIN].async_update() | ||
59 changes: 59 additions & 0 deletions
59
homeassistant/components/islamic_prayer_times/config_flow.py
This file contains hidden or 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,59 @@ | ||
| """Config flow for Islamic Prayer Times integration.""" | ||
| import voluptuous as vol | ||
|
|
||
| from homeassistant import config_entries | ||
| from homeassistant.core import callback | ||
|
|
||
| # pylint: disable=unused-import | ||
| from .const import CALC_METHODS, CONF_CALC_METHOD, DEFAULT_CALC_METHOD, DOMAIN, NAME | ||
springstan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| class IslamicPrayerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): | ||
| """Handle the Islamic Prayer config flow.""" | ||
|
|
||
| VERSION = 1 | ||
| CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL | ||
|
|
||
| @staticmethod | ||
| @callback | ||
| def async_get_options_flow(config_entry): | ||
| """Get the options flow for this handler.""" | ||
| return IslamicPrayerOptionsFlowHandler(config_entry) | ||
|
|
||
| async def async_step_user(self, user_input=None): | ||
| """Handle a flow initialized by the user.""" | ||
| if self._async_current_entries(): | ||
| return self.async_abort(reason="one_instance_allowed") | ||
engrbm87 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if user_input is None: | ||
| return self.async_show_form(step_id="user") | ||
|
|
||
| return self.async_create_entry(title=NAME, data=user_input) | ||
|
|
||
| async def async_step_import(self, import_config): | ||
| """Import from Transmission client config.""" | ||
| return await self.async_step_user(user_input=import_config) | ||
|
|
||
|
|
||
| class IslamicPrayerOptionsFlowHandler(config_entries.OptionsFlow): | ||
| """Handle Islamic Prayer client options.""" | ||
|
|
||
| def __init__(self, config_entry): | ||
| """Initialize options flow.""" | ||
| self.config_entry = config_entry | ||
|
|
||
| async def async_step_init(self, user_input=None): | ||
| """Manage options.""" | ||
| if user_input is not None: | ||
| return self.async_create_entry(title="", data=user_input) | ||
|
|
||
| options = { | ||
| vol.Optional( | ||
| CONF_CALC_METHOD, | ||
| default=self.config_entry.options.get( | ||
| CONF_CALC_METHOD, DEFAULT_CALC_METHOD | ||
| ), | ||
| ): vol.In(CALC_METHODS) | ||
| } | ||
|
|
||
| return self.async_show_form(step_id="init", data_schema=vol.Schema(options)) | ||
This file contains hidden or 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,14 @@ | ||
| """Constants for the Islamic Prayer component.""" | ||
| DOMAIN = "islamic_prayer_times" | ||
| NAME = "Islamic Prayer Times" | ||
| PRAYER_TIMES_ICON = "mdi:calendar-clock" | ||
|
|
||
| SENSOR_TYPES = ["fajr", "sunrise", "dhuhr", "asr", "maghrib", "isha", "midnight"] | ||
|
|
||
| CONF_CALC_METHOD = "calculation_method" | ||
| CONF_SENSORS = "sensors" | ||
|
|
||
| CALC_METHODS = ["karachi", "isna", "mwl", "makkah"] | ||
| DEFAULT_CALC_METHOD = "isna" | ||
|
|
||
| DATA_UPDATED = "Islamic_prayer_data_updated" |
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.