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' # IP van Raspberry Pi waar Sonos API draait 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')}")