Skip to content

Commit

Permalink
Merge pull request #48 from mawaqit/issue-46-update-sensors
Browse files Browse the repository at this point in the history
Fix Issue #46 : Update sensors at 1 AM
  • Loading branch information
ibrahim-zehhaf-mawaqit authored Oct 24, 2023
2 parents d1920c2 + 83dfbb3 commit 9fdce04
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 74 deletions.
144 changes: 75 additions & 69 deletions custom_components/mawaqit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_call_later, async_track_point_in_time
from homeassistant.helpers.event import async_call_later, async_track_point_in_time, async_track_time_change
import homeassistant.util.dt as dt_util
# from homeassistant.helpers import aiohttp_client

Expand All @@ -27,6 +27,7 @@
API,
CONF_CALC_METHOD,
DATA_UPDATED,
UPDATE_TIME,
DEFAULT_CALC_METHOD,
DOMAIN,
USERNAME,
Expand Down Expand Up @@ -163,7 +164,7 @@ def get_new_prayer_times(self):
mosque_id = uuid_servers[indice]

# We get the prayer times of the year from pray_time.txt
f = open('{dir}/data/pray_time.txt'.format(dir=current_dir, name=""))
f = open('{dir}/data/pray_time.txt'.format(dir=current_dir), "r")

data = json.load(f)
calendar = data["calendar"]
Expand All @@ -176,15 +177,19 @@ def get_new_prayer_times(self):
index_day = today.day
day_times = month_times[str(index_day)] # Today's times

prayer_names = ["Fajr", "Shurouq", "Dhuhr", "Asr", "Maghrib", "Isha" ]
prayer_names = ["Fajr", "Shurouq", "Dhuhr", "Asr", "Maghrib", "Isha"]
res = {prayer_names[i]: day_times[i] for i in range(len(prayer_names))}

try:
day_times_tomorrow = month_times[str(index_day + 1)]
except KeyError:
# If index_day + 1 == 32 (or 31) and the month contains only 31 (or 30) days
# We take the first prayer of the following month
day_times_tomorrow = calendar[index_month + 1]["1"]
# We take the first day of the following month (reset 0 if we're in december)
if index_month == 11:
index_next_month = 0
else:
index_next_month = index_month + 1
day_times_tomorrow = calendar[index_next_month]["1"]

now = today.time().strftime("%H:%M")

Expand All @@ -208,10 +213,9 @@ def get_new_prayer_times(self):
res['Next Salat Time'] = next_prayer.split(" ", 1)[1].rsplit(':', 1)[0]
res['Next Salat Name'] = prayer_names[prayers.index(next_prayer)]

# 15 minutes Before Next Prayer
countdown_next_prayer = 15
# 15 minutes Before Next Prayer
res['Next Salat Preparation'] = (datetime.strptime(next_prayer, '%Y-%m-%d %H:%M:%S')-timedelta(minutes=countdown_next_prayer)).strftime('%Y-%m-%d %H:%M:%S').split(" ", 1)[1].rsplit(':', 1)[0]


# if Jumu'a is set as Dhuhr, then Jumu'a time is the same as Friday's Dhuhr time
if data["jumuaAsDuhr"]:
Expand Down Expand Up @@ -263,70 +267,60 @@ def get_new_prayer_times(self):
res2 = {**res, **res1}

return res2


async def async_update_next_salat_sensor(self, *_):
salat_before_update = self.prayer_times_info['Next Salat Name']
prayers = ["Fajr", "Dhuhr", "Asr", "Maghrib", "Isha"]
if salat_before_update != "Isha": # We just retrieve the next salat of the day.
index = prayers.index(salat_before_update) + 1
self.prayer_times_info['Next Salat Name'] = prayers[index]
self.prayer_times_info['Next Salat Time'] = self.prayer_times_info[prayers[index]]

else: # We retrieve the next Fajr (more calcualtions).
current_dir = os.path.dirname(os.path.realpath(__file__))
f = open('{dir}/data/pray_time.txt'.format(dir=current_dir), "r")
data = json.load(f)
calendar = data["calendar"]

today = datetime.today()
index_month = today.month - 1
month_times = calendar[index_month]

async def async_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 Mawaqit midnight.
Traditional Midnight: Isha time + 1 minute
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 Mawaqit prayer times")

now = dt_util.utcnow()
now = dt_util.now()

midnight_dt = self.prayer_times_info["Next Salat Time"]
Fajr_dt = self.prayer_times_info["Fajr"]
Dhuhr_dt = self.prayer_times_info["Dhuhr"]
Asr_dt = self.prayer_times_info["Asr"]
Maghrib_dt = self.prayer_times_info["Maghrib"]
Isha_dt = self.prayer_times_info["Isha"]

prayer_times = [Fajr_dt, Dhuhr_dt, Asr_dt, Maghrib_dt, Isha_dt]

midnight_dt = min(prayer_times)
maghrib_hour = self.prayer_times_info['Maghrib']
maghrib_hour = maghrib_hour.strftime("%H:%M")

# isha + 1 minute because this function is launched 1 minute after 'Isha, (useful only if 'Isha is at 11:59 PM)
isha_hour = self.prayer_times_info['Isha'] + timedelta(minutes=1)
isha_hour = isha_hour.strftime("%H:%M")

# If 'Isha is before 12 AM (Maghrib hour < 'Isha hour), we need to get the next day's Fajr.
# Else, we get the current day's Fajr.
if maghrib_hour < isha_hour:
index_day = today.day + 1
else:
index_day = today.day

try:
day_times = month_times[str(index_day)]
except KeyError:
# If index_day + 1 == 32 (or 31) and the month contains only 31 (or 30) days
# We take the first day of the following month (reset 0 if we're in december)
if index_month == 11:
index_next_month = 0
else:
index_next_month = index_month + 1
day_times = calendar[index_next_month]["1"]
fajr_hour = day_times[0]

if now > dt_util.as_utc(midnight_dt):
next_update_at = midnight_dt + timedelta(days=0, minutes=1, seconds=0)
_LOGGER.debug(
"Midnight is after day the changes so schedule update for after Midnight the next day"
)
else:
_LOGGER.debug(
"Midnight is before the day changes so schedule update for the next start of day"
)
next_update_at = dt_util.start_of_local_day(now + timedelta(days=1))
next_update_at = midnight_dt + timedelta(days=0, minutes=1)
self.prayer_times_info['Next Salat Name'] = "Fajr"
self.prayer_times_info['Next Salat Time'] = dt_util.parse_datetime(f"{today.year}-{today.month}-{index_day} {fajr_hour}:00")

_LOGGER.info("Next update scheduled for: %s", next_update_at)
countdown_next_prayer = 15
self.prayer_times_info['Next Salat Preparation'] = self.prayer_times_info['Next Salat Time'] - timedelta(minutes=countdown_next_prayer)

self.event_unsub = async_track_point_in_time(
self.hass, self.async_update, next_update_at
)
_LOGGER.debug("Next salat info updated, updating sensors")
async_dispatcher_send(self.hass, DATA_UPDATED)

async def async_update(self, *_):
"""Update sensors with new prayer times."""
Expand Down Expand Up @@ -366,9 +360,16 @@ async def async_update(self, *_):
)
else:
self.prayer_times_info[prayer] = time


await self.async_schedule_future_update()

# We schedule updates for next_salat_time and next_salat_name at each prayer time + 1 minute.
prayers = ["Fajr", "Dhuhr", "Asr", "Maghrib", "Isha"]
prayer_times = [self.prayer_times_info[prayer] for prayer in prayers]

for prayer in prayer_times:
next_update_at = prayer + timedelta(minutes=1)
async_track_point_in_time(
self.hass, self.async_update_next_salat_sensor, next_update_at
)

_LOGGER.debug("New prayer times retrieved. Updating sensors.")
async_dispatcher_send(self.hass, DATA_UPDATED)
Expand All @@ -386,6 +387,10 @@ async def async_setup(self):
await self.async_update()
self.config_entry.add_update_listener(self.async_options_updated)

# We update time prayers every day.
h, m, s = UPDATE_TIME
async_track_time_change(self.hass, self.async_update, hour=h, minute=m, second=s)

return True

async def async_add_options(self):
Expand All @@ -404,3 +409,4 @@ async def async_options_updated(hass, entry):
if hass.data[DOMAIN].event_unsub:
hass.data[DOMAIN].event_unsub()
await hass.data[DOMAIN].async_update()

7 changes: 2 additions & 5 deletions custom_components/mawaqit/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
"Isha": "Adhan",
"Jumua": "Adhan",
"Jumua 2": "Adhan",
#"Aid": "Adhan",
#"Aid 2": "Adhan",
"next_mawaqit": "time",
"Fajr Iqama": "",
"Dhuhr Iqama": "",
Expand All @@ -29,8 +27,6 @@
"Mosque_url": "",
"Mosque_image": "",
}



CONF_CALC_METHOD = "calculation_method"

Expand All @@ -39,8 +35,9 @@

DATA_UPDATED = "Mawaqit_prayer_data_updated"

CONF_SERVER = "server"
UPDATE_TIME = (1, 0, 0)

CONF_SERVER = "server"

USERNAME = "user"

Expand Down

0 comments on commit 9fdce04

Please sign in to comment.