De commit introduceert een debug tijdsynchronisatie tussen de cron script, de hoofdpagina en de Flask API. Deze functies maken het mogelijk om de huidige tijd te simuleren met een instelbare offset voor testdoeleinden. Het volume en de gebedstijden passen zich nu aan op basis van deze debug tijd indien actief. Debugger gebruikers kunnen via de nieuwe '/api/debug-time' endpoint de tijd aanpassen. De wijzigingen verbeteren de testbaarheid van de applicatie en zorgen ervoor dat gebedsafroepen en volumebepaling correct functioneren onder simulatieomstandigheden.
234 lines
8.8 KiB
Python
234 lines
8.8 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' # 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')}") |