Adhaan/adhan-webapp/adhan_cron.py
filoor d9e8d9a915 feat(gebedstijden): voeg gebedstijd offsets en UI aanpassingen toe
Gebedstijd offsets zijn toegevoegd waarmee gebruikers tijdaanpassingen kunnen maken aan de tijden verkregen van de VUMG API. Dit biedt meer flexibiliteit door de mogelijkheid te geven om minuten toe te voegen of af te trekken van elke specifieke gebedstijd (Fajr, Zuhr, Asr, Maghrib, Isha). Het template voor instellingen is aangepast om deze nieuwe offset functionaliteit op een gebruiksvriendelijke manier toegankelijk te maken. Ook zijn er kleine correcties uitgevoerd om de seconden correct uit de gebedstijden te halen voor een betere verwerking.
2025-05-27 15:29:42 +02:00

213 lines
7.9 KiB
Python

import requests, json, os
from datetime import datetime, date, timedelta
import time
SETTINGS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'settings.json')
VUMG_API = 'https://www.vumg.nl/?rest_route=/dpt/v1/prayertime&filter=today'
SONOS_API_IP = '192.168.0.114' # Pas aan indien nodig
LOG_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'adhan_cron.log')
LAST_PLAYED_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'last_played.json')
def logregel(message):
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_message = f"[{timestamp}] {message}"
print(log_message) # Voor Docker logs
with open(LOG_PATH, 'a') as log:
log.write(log_message + '\n')
def get_current_volume(settings):
"""Bepaal het juiste volume op basis van de huidige tijd"""
# Fallback naar oude volume als nieuwe instellingen niet bestaan
if 'volume_day' not in settings or 'volume_night' not in settings:
return settings.get('volume', 30)
current_time = datetime.now().strftime('%H:%M')
night_start = settings.get('night_start', '20:00')
day_start = settings.get('day_start', '07:00')
# Converteer tijden naar vergelijkbare format
current_minutes = int(current_time[:2]) * 60 + int(current_time[3:5])
night_minutes = int(night_start[:2]) * 60 + int(night_start[3:5])
day_minutes = int(day_start[:2]) * 60 + int(day_start[3:5])
# Bepaal of het avond is
if night_minutes > day_minutes: # Normale dag/nacht cyclus (bijv. dag 07:00-20:00)
is_night = current_minutes >= night_minutes or current_minutes < day_minutes
else: # Avond gaat over middernacht (bijv. avond 20:00-07:00)
is_night = current_minutes >= night_minutes and current_minutes < day_minutes
if is_night:
volume = settings.get('volume_night', settings.get('volume', 30) // 2)
logregel(f"🌙 Avond volume gebruikt: {volume}")
return volume
else:
volume = settings.get('volume_day', settings.get('volume', 30))
logregel(f"☀️ Dag volume gebruikt: {volume}")
return volume
def apply_prayer_offsets(gebedstijden, settings):
"""Pas offsets toe op gebedstijden"""
offsets = {
'Fajr': settings.get('fajr_offset', 0),
'Zuhr': settings.get('zuhr_offset', 0),
'Asr': settings.get('asr_offset', 0),
'Maghrib': settings.get('maghrib_offset', 0),
'Isha': settings.get('isha_offset', 0)
}
adjusted_times = {}
for prayer, original_time in gebedstijden.items():
offset_minutes = offsets.get(prayer, 0)
if offset_minutes == 0:
adjusted_times[prayer] = original_time
continue
try:
# Parse de originele tijd
time_obj = datetime.strptime(original_time, '%H:%M')
# Voeg offset toe
adjusted_time = time_obj + timedelta(minutes=offset_minutes)
# Converteer terug naar string
adjusted_times[prayer] = adjusted_time.strftime('%H:%M')
if offset_minutes != 0:
logregel(f"📅 {prayer}: {original_time}{adjusted_times[prayer]} ({offset_minutes:+d} min)")
except Exception as e:
logregel(f"⚠️ Fout bij aanpassen {prayer} tijd: {e}")
adjusted_times[prayer] = original_time
return adjusted_times
def check_recent_play(prayer_name):
"""Controleer of deze adhaan recent is afgespeeld (binnen 2 minuten)"""
try:
if os.path.exists(LAST_PLAYED_PATH):
with open(LAST_PLAYED_PATH, 'r') as f:
last_played = json.load(f)
last_time = last_played.get(prayer_name)
if last_time:
last_datetime = datetime.fromisoformat(last_time)
time_diff = (datetime.now() - last_datetime).total_seconds()
if time_diff < 120: # 2 minuten
logregel(f"⏭️ {prayer_name} recent afgespeeld ({int(time_diff)}s geleden), overslaan")
return True
except Exception as e:
logregel(f"Fout bij controleren recent play: {e}")
return False
def mark_as_played(prayer_name):
"""Markeer deze adhaan als afgespeeld"""
try:
last_played = {}
if os.path.exists(LAST_PLAYED_PATH):
with open(LAST_PLAYED_PATH, 'r') as f:
last_played = json.load(f)
last_played[prayer_name] = datetime.now().isoformat()
with open(LAST_PLAYED_PATH, 'w') as f:
json.dump(last_played, f)
except Exception as e:
logregel(f"Fout bij markeren als afgespeeld: {e}")
def play_sonos_clip(zone, audio_clip, volume, prayer_name):
"""Speel een clip af op een specifieke Sonos zone met error handling"""
try:
# Stop eerst alle audio op deze zone
stop_url = f"http://{SONOS_API_IP}:5005/{zone}/pause"
requests.get(stop_url, timeout=2)
time.sleep(0.5) # Korte pauze
# Speel de clip af
clip_url = f"http://{SONOS_API_IP}:5005/{zone}/clip/{audio_clip}/{volume}"
response = requests.get(clip_url, timeout=10)
if response.status_code == 200:
logregel(f"✅ AFGESPEELD {prayer_name} op {zone} ({audio_clip}, volume {volume})")
return True
else:
logregel(f"❌ HTTP {response.status_code} voor {zone}: {response.text[:100]}")
return False
except requests.exceptions.Timeout:
logregel(f"⏱️ TIMEOUT bij {zone} voor {prayer_name}")
return False
except Exception as e:
logregel(f"❌ FOUT Sonos {zone} {prayer_name}: {e}")
return False
now = datetime.now().strftime('%H:%M')
logregel(f"CRON gestart, huidige tijd: {now}")
# Laad settings
try:
with open(SETTINGS_PATH) as f:
settings = json.load(f)
except Exception as e:
logregel(f"Fout bij laden settings: {e}")
exit(1)
# Controleer mute-status
if settings.get('mute', False):
logregel("Adhaan niet afgespeeld: mute staat aan.")
exit(0)
# Haal gebedstijden op
try:
res = requests.get(VUMG_API, timeout=10)
res.raise_for_status()
data = res.json()[0]
gebedstijden = {
"Fajr": data.get("fajr_jamah", "00:00")[:5], # Haal seconden weg
"Zuhr": data.get("zuhr_jamah", "00:00")[:5], # Haal seconden weg
"Asr": data.get("asr_jamah", "00:00")[:5], # Haal seconden weg
"Maghrib": data.get("maghrib_jamah", "00:00")[:5], # Haal seconden weg
"Isha": data.get("isha_jamah", "00:00")[:5] # Haal seconden weg
}
except Exception as e:
logregel(f"Fout bij ophalen gebedstijden: {e}")
exit(1)
# Pas offsets toe op gebedstijden
gebedstijden = apply_prayer_offsets(gebedstijden, settings)
# Check voor gebedstijd
for naam, tijd in gebedstijden.items():
if tijd[:5] == now: # Alleen uren:minuten vergelijken
# Controleer of recent afgespeeld
if check_recent_play(naam):
continue
logregel(f"🕌 GEBEDSTIJD GEDETECTEERD: {naam} om {tijd}")
# Markeer als afgespeeld VOOR het afspelen
mark_as_played(naam)
# Speel af op alle zones
success_count = 0
zones = settings.get('zones', ['Woonkamer'])
audio_clip = settings.get('audio_clip', 'adhan1.mp3')
volume = get_current_volume(settings)
for zone in zones:
if play_sonos_clip(zone, audio_clip, volume, naam):
success_count += 1
time.sleep(1) # Pauze tussen zones
if success_count > 0:
logregel(f"🎵 Adhaan succesvol afgespeeld op {success_count}/{len(zones)} zones")
else:
logregel(f"❌ Adhaan kon niet worden afgespeeld op geen enkele zone")
break # Stop na eerste match
logregel(f"CRON voltooid om {datetime.now().strftime('%H:%M:%S')}")