Adhaan/adhan-webapp/adhan_cron.py
filoor e66173d28d refactor(config): verplaats SONOS_API_IP naar config module
SONOS_API_IP is verplaatst van adhan_cron.py naar de config module om de configuratiegegevens centraler en onderhoudbaarder te maken. Deze wijziging verbetert de leesbaarheid van de codebase en faciliteert eenvoudiger aanpassingen aan API-gerelateerde configuraties zonder direct de hoofdcode te moeten wijzigen.
2025-05-28 19:19:23 +02:00

234 lines
8.8 KiB
Python

import requests, json, os
from datetime import datetime, date, timedelta
import time
from config import SONOS_API_IP
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'
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')
FLASK_API_URL = 'http://localhost:80' # Flask app URL
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_time():
"""Haal de huidige tijd op, gebruik debug tijd als actief"""
try:
# Probeer debug tijd API
response = requests.get(f'{FLASK_API_URL}/api/debug-time', timeout=3)
if response.status_code == 200:
data = response.json()
if data.get('success') and data.get('debug_active'):
debug_time = data.get('current_time_display', '')
logregel(f"🔧 CRON gebruikt debug tijd: {debug_time}")
return debug_time
except Exception as e:
logregel(f"Debug tijd API niet beschikbaar: {e}")
# Fallback naar normale tijd
normal_time = datetime.now().strftime('%H:%M')
return normal_time
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)
# Gebruik debug tijd als beschikbaar
current_time = get_current_time()
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} (tijd: {current_time})")
return volume
else:
volume = settings.get('volume_day', settings.get('volume', 30))
logregel(f"☀️ Dag volume gebruikt: {volume} (tijd: {current_time})")
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
# Gebruik debug tijd als beschikbaar
now = get_current_time()
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')}")