Skip to content

Commit 9fdce04

Browse files
Merge pull request #48 from mawaqit/issue-46-update-sensors
Fix Issue #46 : Update sensors at 1 AM
2 parents d1920c2 + 83dfbb3 commit 9fdce04

File tree

2 files changed

+77
-74
lines changed

2 files changed

+77
-74
lines changed

custom_components/mawaqit/__init__.py

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from homeassistant.exceptions import ConfigEntryNotReady
1919
from homeassistant.helpers import config_validation as cv
2020
from homeassistant.helpers.dispatcher import async_dispatcher_send
21-
from homeassistant.helpers.event import async_call_later, async_track_point_in_time
21+
from homeassistant.helpers.event import async_call_later, async_track_point_in_time, async_track_time_change
2222
import homeassistant.util.dt as dt_util
2323
# from homeassistant.helpers import aiohttp_client
2424

@@ -27,6 +27,7 @@
2727
API,
2828
CONF_CALC_METHOD,
2929
DATA_UPDATED,
30+
UPDATE_TIME,
3031
DEFAULT_CALC_METHOD,
3132
DOMAIN,
3233
USERNAME,
@@ -163,7 +164,7 @@ def get_new_prayer_times(self):
163164
mosque_id = uuid_servers[indice]
164165

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

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

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

182183
try:
183184
day_times_tomorrow = month_times[str(index_day + 1)]
184185
except KeyError:
185186
# If index_day + 1 == 32 (or 31) and the month contains only 31 (or 30) days
186-
# We take the first prayer of the following month
187-
day_times_tomorrow = calendar[index_month + 1]["1"]
187+
# We take the first day of the following month (reset 0 if we're in december)
188+
if index_month == 11:
189+
index_next_month = 0
190+
else:
191+
index_next_month = index_month + 1
192+
day_times_tomorrow = calendar[index_next_month]["1"]
188193

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

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

211-
# 15 minutes Before Next Prayer
212216
countdown_next_prayer = 15
217+
# 15 minutes Before Next Prayer
213218
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]
214-
215219

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

265269
return res2
270+
271+
272+
async def async_update_next_salat_sensor(self, *_):
273+
salat_before_update = self.prayer_times_info['Next Salat Name']
274+
prayers = ["Fajr", "Dhuhr", "Asr", "Maghrib", "Isha"]
275+
if salat_before_update != "Isha": # We just retrieve the next salat of the day.
276+
index = prayers.index(salat_before_update) + 1
277+
self.prayer_times_info['Next Salat Name'] = prayers[index]
278+
self.prayer_times_info['Next Salat Time'] = self.prayer_times_info[prayers[index]]
279+
280+
else: # We retrieve the next Fajr (more calcualtions).
281+
current_dir = os.path.dirname(os.path.realpath(__file__))
282+
f = open('{dir}/data/pray_time.txt'.format(dir=current_dir), "r")
283+
data = json.load(f)
284+
calendar = data["calendar"]
266285

286+
today = datetime.today()
287+
index_month = today.month - 1
288+
month_times = calendar[index_month]
267289

268-
async def async_schedule_future_update(self):
269-
"""Schedule future update for sensors.
270-
271-
Midnight is a calculated time. The specifics of the calculation
272-
depends on the method of the prayer time calculation. This calculated
273-
midnight is the time at which the time to pray the Isha prayers have
274-
expired.
275-
276-
Calculated Midnight: The Mawaqit midnight.
277-
Traditional Midnight: Isha time + 1 minute
278-
279-
Update logic for prayer times:
280-
281-
If the Calculated Midnight is before the traditional midnight then wait
282-
until the traditional midnight to run the update. This way the day
283-
will have changed over and we don't need to do any fancy calculations.
284-
285-
If the Calculated Midnight is after the traditional midnight, then wait
286-
until after the calculated Midnight. We don't want to update the prayer
287-
times too early or else the timings might be incorrect.
288-
289-
Example:
290-
calculated midnight = 11:23PM (before traditional midnight)
291-
Update time: 12:00AM
292-
293-
calculated midnight = 1:35AM (after traditional midnight)
294-
update time: 1:36AM.
295-
296-
"""
297-
_LOGGER.debug("Scheduling next update for Mawaqit prayer times")
298-
299-
now = dt_util.utcnow()
300-
now = dt_util.now()
301-
302-
midnight_dt = self.prayer_times_info["Next Salat Time"]
303-
Fajr_dt = self.prayer_times_info["Fajr"]
304-
Dhuhr_dt = self.prayer_times_info["Dhuhr"]
305-
Asr_dt = self.prayer_times_info["Asr"]
306-
Maghrib_dt = self.prayer_times_info["Maghrib"]
307-
Isha_dt = self.prayer_times_info["Isha"]
308-
309-
prayer_times = [Fajr_dt, Dhuhr_dt, Asr_dt, Maghrib_dt, Isha_dt]
310-
311-
midnight_dt = min(prayer_times)
290+
maghrib_hour = self.prayer_times_info['Maghrib']
291+
maghrib_hour = maghrib_hour.strftime("%H:%M")
292+
293+
# isha + 1 minute because this function is launched 1 minute after 'Isha, (useful only if 'Isha is at 11:59 PM)
294+
isha_hour = self.prayer_times_info['Isha'] + timedelta(minutes=1)
295+
isha_hour = isha_hour.strftime("%H:%M")
296+
297+
# If 'Isha is before 12 AM (Maghrib hour < 'Isha hour), we need to get the next day's Fajr.
298+
# Else, we get the current day's Fajr.
299+
if maghrib_hour < isha_hour:
300+
index_day = today.day + 1
301+
else:
302+
index_day = today.day
303+
304+
try:
305+
day_times = month_times[str(index_day)]
306+
except KeyError:
307+
# If index_day + 1 == 32 (or 31) and the month contains only 31 (or 30) days
308+
# We take the first day of the following month (reset 0 if we're in december)
309+
if index_month == 11:
310+
index_next_month = 0
311+
else:
312+
index_next_month = index_month + 1
313+
day_times = calendar[index_next_month]["1"]
314+
fajr_hour = day_times[0]
312315

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

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

327-
self.event_unsub = async_track_point_in_time(
328-
self.hass, self.async_update, next_update_at
329-
)
322+
_LOGGER.debug("Next salat info updated, updating sensors")
323+
async_dispatcher_send(self.hass, DATA_UPDATED)
330324

331325
async def async_update(self, *_):
332326
"""Update sensors with new prayer times."""
@@ -366,9 +360,16 @@ async def async_update(self, *_):
366360
)
367361
else:
368362
self.prayer_times_info[prayer] = time
369-
370-
371-
await self.async_schedule_future_update()
363+
364+
# We schedule updates for next_salat_time and next_salat_name at each prayer time + 1 minute.
365+
prayers = ["Fajr", "Dhuhr", "Asr", "Maghrib", "Isha"]
366+
prayer_times = [self.prayer_times_info[prayer] for prayer in prayers]
367+
368+
for prayer in prayer_times:
369+
next_update_at = prayer + timedelta(minutes=1)
370+
async_track_point_in_time(
371+
self.hass, self.async_update_next_salat_sensor, next_update_at
372+
)
372373

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

390+
# We update time prayers every day.
391+
h, m, s = UPDATE_TIME
392+
async_track_time_change(self.hass, self.async_update, hour=h, minute=m, second=s)
393+
389394
return True
390395

391396
async def async_add_options(self):
@@ -404,3 +409,4 @@ async def async_options_updated(hass, entry):
404409
if hass.data[DOMAIN].event_unsub:
405410
hass.data[DOMAIN].event_unsub()
406411
await hass.data[DOMAIN].async_update()
412+

custom_components/mawaqit/const.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
"Isha": "Adhan",
1414
"Jumua": "Adhan",
1515
"Jumua 2": "Adhan",
16-
#"Aid": "Adhan",
17-
#"Aid 2": "Adhan",
1816
"next_mawaqit": "time",
1917
"Fajr Iqama": "",
2018
"Dhuhr Iqama": "",
@@ -29,8 +27,6 @@
2927
"Mosque_url": "",
3028
"Mosque_image": "",
3129
}
32-
33-
3430

3531
CONF_CALC_METHOD = "calculation_method"
3632

@@ -39,8 +35,9 @@
3935

4036
DATA_UPDATED = "Mawaqit_prayer_data_updated"
4137

42-
CONF_SERVER = "server"
38+
UPDATE_TIME = (1, 0, 0)
4339

40+
CONF_SERVER = "server"
4441

4542
USERNAME = "user"
4643

0 commit comments

Comments
 (0)