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.
213 lines
7.9 KiB
Python
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')}") |