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.
731 lines
27 KiB
Python
731 lines
27 KiB
Python
from flask import Flask, render_template, request, redirect, send_from_directory, jsonify, request as flask_request
|
|
import requests, json, os, random
|
|
from datetime import datetime
|
|
from config import *
|
|
from hijridate import Gregorian
|
|
|
|
app = Flask(__name__)
|
|
|
|
# Voeg cache-control headers toe voor statische bestanden
|
|
@app.after_request
|
|
def add_header(response):
|
|
if 'Cache-Control' not in response.headers:
|
|
response.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
|
|
return response
|
|
|
|
# Specifieke route voor statische bestanden met cache-control
|
|
@app.route('/static/<path:filename>')
|
|
def serve_static(filename):
|
|
return send_from_directory('static', filename, cache_timeout=0)
|
|
|
|
SETTINGS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'settings.json')
|
|
HADITHS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'hadiths.json')
|
|
VUMG_API = 'https://www.vumg.nl/?rest_route=/dpt/v1/prayertime&filter=today'
|
|
CLIPS_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static', 'clips')
|
|
SONOS_API_IP = '192.168.0.114' # IP van Raspberry Pi waar Sonos API draait
|
|
|
|
# Globale variabelen
|
|
debug_time_offset = 0 # Offset in seconden voor debug mode
|
|
debug_mode_active = False
|
|
|
|
def fetch_weather_data():
|
|
"""Haalt weersinformatie op voor de geconfigureerde locatie"""
|
|
try:
|
|
params = {
|
|
'q': WEATHER_LOCATION,
|
|
'appid': OPENWEATHER_API_KEY,
|
|
'units': 'metric',
|
|
'lang': 'nl'
|
|
}
|
|
response = requests.get('https://api.openweathermap.org/data/2.5/weather', params=params, timeout=5)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
|
|
weather_info = {
|
|
'temperature': round(data['main']['temp']),
|
|
'feels_like': round(data['main']['feels_like']),
|
|
'description': data['weather'][0]['description'].capitalize(),
|
|
'humidity': data['main']['humidity'],
|
|
'wind_speed': round(data['wind']['speed'] * 3.6), # m/s naar km/h
|
|
'icon': data['weather'][0]['icon']
|
|
}
|
|
return weather_info
|
|
except Exception as e:
|
|
print(f"⚠️ Fout bij ophalen weerdata: {e}")
|
|
return {
|
|
'temperature': '--',
|
|
'feels_like': '--',
|
|
'description': 'Weer niet beschikbaar',
|
|
'humidity': '--',
|
|
'wind_speed': '--',
|
|
'icon': '01d'
|
|
}
|
|
|
|
def load_hadith():
|
|
try:
|
|
with open(HADITHS_PATH) as f:
|
|
hadiths = json.load(f)['hadiths']
|
|
return random.choice(hadiths)
|
|
except Exception as e:
|
|
print(f"⚠️ Fout bij laden van hadith: {e}")
|
|
return {"text": "De daden die Allah het meest liefheeft zijn degenen die regelmatig worden verricht, zelfs als ze klein zijn.", "bron": "Sahih al-Bukhari"}
|
|
|
|
def load_settings():
|
|
try:
|
|
if os.path.exists(SETTINGS_PATH) and os.path.getsize(SETTINGS_PATH) > 0:
|
|
with open(SETTINGS_PATH) as f:
|
|
return json.load(f)
|
|
except Exception as e:
|
|
print(f"⚠️ Fout bij laden van settings: {e}")
|
|
return {"volume": 30, "zones": ["Woonkamer"], "audio_clip": "adhan1.mp3"}
|
|
|
|
def get_current_volume(settings):
|
|
"""Bepaal het juiste volume op basis van de huidige tijd"""
|
|
from datetime import datetime, timedelta
|
|
|
|
# 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 actief
|
|
global debug_mode_active, debug_time_offset
|
|
if debug_mode_active:
|
|
current_time = (datetime.now() + timedelta(seconds=debug_time_offset)).strftime('%H:%M')
|
|
print(f"🔧 Volume bepaling gebruikt debug tijd: {current_time}")
|
|
else:
|
|
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)
|
|
print(f"🌙 Avond volume gebruikt: {volume} (tijd: {current_time})")
|
|
return volume
|
|
else:
|
|
volume = settings.get('volume_day', settings.get('volume', 30))
|
|
print(f"☀️ Dag volume gebruikt: {volume} (tijd: {current_time})")
|
|
return volume
|
|
|
|
def apply_prayer_offsets(gebedstijden, settings):
|
|
"""Pas offsets toe op gebedstijden"""
|
|
from datetime import datetime, timedelta
|
|
|
|
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:
|
|
print(f"📅 {prayer}: {original_time} → {adjusted_times[prayer]} ({offset_minutes:+d} min)")
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ Fout bij aanpassen {prayer} tijd: {e}")
|
|
adjusted_times[prayer] = original_time
|
|
|
|
return adjusted_times
|
|
|
|
def fetch_sonos_zones():
|
|
try:
|
|
res = requests.get(f'http://{SONOS_API_IP}:5005/zones', timeout=5)
|
|
res.raise_for_status()
|
|
data = res.json()
|
|
zones = []
|
|
for group in data:
|
|
for player in group['members']:
|
|
zones.append(player['roomName'])
|
|
return sorted(set(zones))
|
|
except Exception as e:
|
|
print(f'Fout bij ophalen Sonos-zones: {e}')
|
|
return ['Woonkamer', 'Slaapkamer', 'Keuken']
|
|
|
|
def get_date_info():
|
|
"""Genereert zowel Gregoriaanse als Hijri datum informatie"""
|
|
now = datetime.now()
|
|
|
|
# Gregoriaanse datum
|
|
gregorian_date = now.strftime('%A %d %B %Y')
|
|
gregorian_short = now.strftime('%d-%m-%Y')
|
|
|
|
# Nederlandse maandnamen
|
|
dutch_months = {
|
|
'January': 'januari', 'February': 'februari', 'March': 'maart',
|
|
'April': 'april', 'May': 'mei', 'June': 'juni',
|
|
'July': 'juli', 'August': 'augustus', 'September': 'september',
|
|
'October': 'oktober', 'November': 'november', 'December': 'december'
|
|
}
|
|
|
|
# Nederlandse dagnamen
|
|
dutch_days = {
|
|
'Monday': 'maandag', 'Tuesday': 'dinsdag', 'Wednesday': 'woensdag',
|
|
'Thursday': 'donderdag', 'Friday': 'vrijdag', 'Saturday': 'zaterdag', 'Sunday': 'zondag'
|
|
}
|
|
|
|
# Vervang Engelse namen door Nederlandse
|
|
for eng, nl in dutch_months.items():
|
|
gregorian_date = gregorian_date.replace(eng, nl)
|
|
for eng, nl in dutch_days.items():
|
|
gregorian_date = gregorian_date.replace(eng, nl)
|
|
|
|
try:
|
|
# Converteer naar Hijri datum
|
|
hijri_date = Gregorian(now.year, now.month, now.day).to_hijri()
|
|
|
|
# Arabische maandnamen
|
|
hijri_months = [
|
|
'محرم', 'صفر', 'ربيع الأول', 'ربيع الثاني', 'جمادى الأولى', 'جمادى الثانية',
|
|
'رجب', 'شعبان', 'رمضان', 'شوال', 'ذو القعدة', 'ذو الحجة'
|
|
]
|
|
|
|
# Nederlandse maandnamen voor Hijri
|
|
hijri_months_nl = [
|
|
'Muharram', 'Safar', 'Rabi al-Awwal', 'Rabi al-Thani', 'Jumada al-Awwal', 'Jumada al-Thani',
|
|
'Rajab', 'Sha\'ban', 'Ramadan', 'Shawwal', 'Dhu al-Qi\'dah', 'Dhu al-Hijjah'
|
|
]
|
|
|
|
hijri_arabic = f"{hijri_date.day} {hijri_months[hijri_date.month - 1]} {hijri_date.year} هـ"
|
|
hijri_dutch = f"{hijri_date.day} {hijri_months_nl[hijri_date.month - 1]} {hijri_date.year} AH"
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ Fout bij Hijri conversie: {e}")
|
|
hijri_arabic = "التاريخ الهجري غير متاح"
|
|
hijri_dutch = "Hijri datum niet beschikbaar"
|
|
|
|
return {
|
|
'gregorian_full': gregorian_date,
|
|
'gregorian_short': gregorian_short,
|
|
'hijri_arabic': hijri_arabic,
|
|
'hijri_dutch': hijri_dutch,
|
|
'current_time': now.strftime('%H:%M')
|
|
}
|
|
|
|
@app.route('/')
|
|
def index():
|
|
settings = load_settings()
|
|
next_time = "Onbekend"
|
|
next_name = "Onbekend"
|
|
debug_data = {}
|
|
gebedstijden = {}
|
|
hadith = load_hadith()
|
|
weather = fetch_weather_data()
|
|
date_info = get_date_info()
|
|
|
|
try:
|
|
res = requests.get(VUMG_API)
|
|
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
|
|
}
|
|
|
|
# Pas offsets toe op gebedstijden
|
|
gebedstijden = apply_prayer_offsets(gebedstijden, settings)
|
|
|
|
now = datetime.now().strftime('%H:%M')
|
|
for naam, tijd in gebedstijden.items():
|
|
if tijd > now:
|
|
next_time = tijd
|
|
next_name = naam
|
|
break
|
|
else:
|
|
next_time = list(gebedstijden.values())[0]
|
|
next_name = list(gebedstijden.keys())[0]
|
|
|
|
debug_data = {
|
|
"api_response": data,
|
|
"gebedstijden": gebedstijden,
|
|
"now": now,
|
|
"next_time": next_time,
|
|
"next_name": next_name
|
|
}
|
|
|
|
except Exception as e:
|
|
print("❌ Fout bij ophalen/verwerken van gebedstijden:", e)
|
|
|
|
dua = "اللّهُمَّ اجْعَلْ صَلاتِي نُورًا"
|
|
return render_template('index.html',
|
|
next_time=next_time,
|
|
next_name=next_name,
|
|
dua=dua,
|
|
hadith=hadith,
|
|
gebedstijden=gebedstijden,
|
|
debug=debug_data,
|
|
settings=settings,
|
|
weather=weather,
|
|
date_info=date_info)
|
|
|
|
@app.route('/instellingen', methods=['GET', 'POST'])
|
|
def instellingen():
|
|
settings = load_settings()
|
|
clips = [f for f in os.listdir(CLIPS_PATH) if f.endswith('.mp3') or f.endswith('.wav')]
|
|
alle_zones = fetch_sonos_zones()
|
|
|
|
if request.method == 'POST':
|
|
# Nieuwe volume instellingen
|
|
if 'volume_day' in request.form and 'volume_night' in request.form:
|
|
settings['volume_day'] = int(request.form['volume_day'])
|
|
settings['volume_night'] = int(request.form['volume_night'])
|
|
settings['night_start'] = request.form['night_start']
|
|
settings['day_start'] = request.form['day_start']
|
|
# Update oude volume voor backward compatibility
|
|
settings['volume'] = settings['volume_day']
|
|
else:
|
|
# Fallback: gebruik default waarden als velden ontbreken
|
|
settings['volume_day'] = settings.get('volume_day', 15)
|
|
settings['volume_night'] = settings.get('volume_night', 8)
|
|
settings['night_start'] = settings.get('night_start', '20:00')
|
|
settings['day_start'] = settings.get('day_start', '07:00')
|
|
settings['volume'] = settings['volume_day']
|
|
|
|
# Gebedstijd offsets
|
|
settings['fajr_offset'] = int(request.form.get('fajr_offset', 0))
|
|
settings['zuhr_offset'] = int(request.form.get('zuhr_offset', 0))
|
|
settings['asr_offset'] = int(request.form.get('asr_offset', 0))
|
|
settings['maghrib_offset'] = int(request.form.get('maghrib_offset', 0))
|
|
settings['isha_offset'] = int(request.form.get('isha_offset', 0))
|
|
|
|
# Adzkaar instellingen
|
|
settings['adzkaar_enabled'] = 'adzkaar_enabled' in request.form
|
|
settings['adzkaar_duration'] = int(request.form.get('adzkaar_duration', 5))
|
|
|
|
# Hadith instellingen
|
|
settings['hadith_interval_seconds'] = int(request.form.get('hadith_interval_seconds', 30))
|
|
|
|
settings['zones'] = request.form.getlist('zones')
|
|
settings['audio_clip'] = request.form['audio_clip']
|
|
|
|
with open(SETTINGS_PATH, 'w') as f:
|
|
json.dump(settings, f, indent=2)
|
|
|
|
if 'test_clip' in request.form:
|
|
# Gebruik het juiste volume voor de test
|
|
test_volume = get_current_volume(settings)
|
|
for zone in settings['zones']:
|
|
url = f"http://{SONOS_API_IP}:5005/{zone}/clip/{settings['audio_clip']}/{test_volume}"
|
|
try:
|
|
r = requests.get(url, timeout=3)
|
|
print(f"🎵 Test clip verzonden naar {zone}, status: {r.status_code}")
|
|
except Exception as e:
|
|
print(f"❌ Fout bij afspelen op zone {zone}: {e}")
|
|
|
|
return redirect('/instellingen')
|
|
|
|
return render_template('settings.html',
|
|
settings=settings,
|
|
alle_zones=alle_zones,
|
|
clips=clips)
|
|
|
|
@app.route('/api/hadith')
|
|
def api_hadith():
|
|
hadith = load_hadith()
|
|
return jsonify(hadith)
|
|
|
|
@app.route('/api/mute', methods=['POST'])
|
|
def toggle_mute():
|
|
try:
|
|
data = flask_request.get_json()
|
|
mute = data.get('mute', False)
|
|
with open(SETTINGS_PATH, 'r+') as f:
|
|
settings = json.load(f)
|
|
settings['mute'] = mute
|
|
f.seek(0)
|
|
json.dump(settings, f, indent=2)
|
|
f.truncate()
|
|
return jsonify({'success': True, 'mute': mute})
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
@app.route('/api/weather')
|
|
def api_weather():
|
|
"""API endpoint voor het ophalen van actuele weerdata"""
|
|
weather = fetch_weather_data()
|
|
return jsonify(weather)
|
|
|
|
@app.route('/api/date-info')
|
|
def api_date_info():
|
|
"""API endpoint voor het ophalen van actuele datum informatie"""
|
|
date_info = get_date_info()
|
|
return jsonify(date_info)
|
|
|
|
@app.route('/api/test-audio', methods=['POST'])
|
|
def test_audio():
|
|
"""Test een audio bestand lokaal in de browser"""
|
|
try:
|
|
data = flask_request.get_json()
|
|
audio_file = data.get('audio_file', 'adhan1.mp3')
|
|
|
|
# Controleer of het bestand bestaat
|
|
audio_path = os.path.join(CLIPS_PATH, audio_file)
|
|
if not os.path.exists(audio_path):
|
|
return jsonify({'success': False, 'error': 'Audio bestand niet gevonden'}), 404
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'message': f'Audio bestand {audio_file} is beschikbaar',
|
|
'url': f'/static/clips/{audio_file}'
|
|
})
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
@app.route('/debug')
|
|
def debug():
|
|
"""Debug pagina voor het testen van adhaan functionaliteit"""
|
|
settings = load_settings()
|
|
|
|
# Check of debug mode is ingeschakeld
|
|
if not settings.get('debug_mode', False):
|
|
return redirect('/')
|
|
|
|
gebedstijden = {}
|
|
|
|
try:
|
|
res = requests.get(VUMG_API)
|
|
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
|
|
}
|
|
|
|
# Pas offsets toe op gebedstijden
|
|
gebedstijden = apply_prayer_offsets(gebedstijden, settings)
|
|
except Exception as e:
|
|
print("❌ Fout bij ophalen gebedstijden voor debug:", e)
|
|
# Fallback tijden voor testing
|
|
gebedstijden = {
|
|
"Fajr": "06:00",
|
|
"Zuhr": "12:30",
|
|
"Asr": "15:00",
|
|
"Maghrib": "17:30",
|
|
"Isha": "19:00"
|
|
}
|
|
|
|
# Pas ook offsets toe op fallback tijden
|
|
gebedstijden = apply_prayer_offsets(gebedstijden, settings)
|
|
|
|
return render_template('debug.html',
|
|
gebedstijden=gebedstijden,
|
|
settings=settings)
|
|
|
|
@app.route('/api/debug-adhaan', methods=['POST'])
|
|
def debug_adhaan():
|
|
"""API endpoint voor debug adhaan testing"""
|
|
import time
|
|
|
|
# Check of debug mode is ingeschakeld
|
|
settings = load_settings()
|
|
if not settings.get('debug_mode', False):
|
|
return jsonify({'success': False, 'error': 'Debug mode is niet ingeschakeld'}), 403
|
|
|
|
try:
|
|
data = flask_request.get_json()
|
|
prayer_name = data.get('prayer', 'Test')
|
|
test_time = data.get('time', 'Onbekend')
|
|
|
|
# Check mute status
|
|
if settings.get('mute', False):
|
|
return jsonify({
|
|
'success': False,
|
|
'error': 'Adhaan niet afgespeeld: mute staat aan',
|
|
'muted': True
|
|
})
|
|
|
|
# Verbeterde Sonos afspeling
|
|
success_count = 0
|
|
error_messages = []
|
|
zones = settings.get('zones', ['Woonkamer'])
|
|
audio_clip = settings.get('audio_clip', 'adhan1.mp3')
|
|
volume = get_current_volume(settings)
|
|
|
|
for zone in zones:
|
|
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:
|
|
success_count += 1
|
|
print(f"🔧 DEBUG: Adhaan afgespeeld op {zone} voor {prayer_name} om {test_time}")
|
|
else:
|
|
error_messages.append(f"{zone}: HTTP {response.status_code}")
|
|
|
|
except requests.exceptions.Timeout:
|
|
error_messages.append(f"{zone}: Timeout")
|
|
except Exception as e:
|
|
error_messages.append(f"{zone}: {str(e)}")
|
|
|
|
# Pauze tussen zones
|
|
if len(zones) > 1:
|
|
time.sleep(1)
|
|
|
|
if success_count > 0:
|
|
return jsonify({
|
|
'success': True,
|
|
'message': f'Adhaan afgespeeld op {success_count}/{len(zones)} zone(s)',
|
|
'errors': error_messages if error_messages else None
|
|
})
|
|
else:
|
|
return jsonify({
|
|
'success': False,
|
|
'error': f'Geen zones bereikbaar: {", ".join(error_messages)}'
|
|
})
|
|
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
@app.route('/api/sonos-status')
|
|
def sonos_status():
|
|
"""API endpoint voor Sonos status controle"""
|
|
try:
|
|
settings = load_settings()
|
|
zones = settings.get('zones', ['Woonkamer'])
|
|
status_info = {}
|
|
|
|
for zone in zones:
|
|
try:
|
|
# Haal zone status op
|
|
status_url = f"http://{SONOS_API_IP}:5005/{zone}/state"
|
|
response = requests.get(status_url, timeout=3)
|
|
|
|
if response.status_code == 200:
|
|
zone_data = response.json()
|
|
status_info[zone] = {
|
|
'status': 'online',
|
|
'playbackState': zone_data.get('playbackState', 'unknown'),
|
|
'currentTrack': zone_data.get('currentTrack', {}).get('title', 'Geen track'),
|
|
'volume': zone_data.get('volume', 0)
|
|
}
|
|
else:
|
|
status_info[zone] = {'status': 'error', 'error': f'HTTP {response.status_code}'}
|
|
|
|
except Exception as e:
|
|
status_info[zone] = {'status': 'offline', 'error': str(e)}
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'zones': status_info,
|
|
'api_ip': SONOS_API_IP
|
|
})
|
|
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
@app.route('/api/sonos-stop', methods=['POST'])
|
|
def sonos_stop():
|
|
"""API endpoint om alle Sonos zones te stoppen"""
|
|
try:
|
|
settings = load_settings()
|
|
zones = settings.get('zones', ['Woonkamer'])
|
|
stopped_zones = []
|
|
|
|
for zone in zones:
|
|
try:
|
|
stop_url = f"http://{SONOS_API_IP}:5005/{zone}/pause"
|
|
response = requests.get(stop_url, timeout=3)
|
|
|
|
if response.status_code == 200:
|
|
stopped_zones.append(zone)
|
|
|
|
except Exception as e:
|
|
print(f"Fout bij stoppen {zone}: {e}")
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'message': f'Audio gestopt op {len(stopped_zones)} zone(s)',
|
|
'stopped_zones': stopped_zones
|
|
})
|
|
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
@app.route('/quran')
|
|
def quran():
|
|
"""Quran speler pagina"""
|
|
settings = load_settings()
|
|
gebedstijden = {}
|
|
|
|
try:
|
|
res = requests.get(VUMG_API)
|
|
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
|
|
}
|
|
|
|
# Pas offsets toe op gebedstijden
|
|
gebedstijden = apply_prayer_offsets(gebedstijden, settings)
|
|
except Exception as e:
|
|
print("❌ Fout bij ophalen gebedstijden voor quran pagina:", e)
|
|
# Fallback tijden
|
|
gebedstijden = {
|
|
"Fajr": "06:00",
|
|
"Zuhr": "12:30",
|
|
"Asr": "15:00",
|
|
"Maghrib": "17:30",
|
|
"Isha": "19:00"
|
|
}
|
|
|
|
# Pas ook offsets toe op fallback tijden
|
|
gebedstijden = apply_prayer_offsets(gebedstijden, settings)
|
|
|
|
return render_template('quran.html',
|
|
gebedstijden=gebedstijden,
|
|
settings=settings)
|
|
|
|
@app.route('/adzkaar')
|
|
def adzkaar():
|
|
"""Adzkaar pagina na gebed"""
|
|
settings = load_settings()
|
|
duration_minutes = settings.get('adzkaar_duration', 5) # Default 5 minuten
|
|
|
|
return render_template('adzkaar.html',
|
|
duration_minutes=duration_minutes,
|
|
settings=settings)
|
|
|
|
@app.route('/api/trigger-adzkaar', methods=['POST'])
|
|
def trigger_adzkaar():
|
|
"""API endpoint om Adzkaar scherm te triggeren (voor debug)"""
|
|
try:
|
|
settings = load_settings()
|
|
|
|
# Check of Adzkaar is ingeschakeld
|
|
if not settings.get('adzkaar_enabled', True):
|
|
return jsonify({
|
|
'success': False,
|
|
'error': 'Adzkaar is uitgeschakeld in instellingen'
|
|
})
|
|
|
|
duration = settings.get('adzkaar_duration', 5)
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'message': f'Adzkaar scherm wordt getoond voor {duration} minuten',
|
|
'duration': duration,
|
|
'url': '/adzkaar'
|
|
})
|
|
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
@app.route('/api/debug-time', methods=['GET', 'POST'])
|
|
def debug_time():
|
|
"""API endpoint voor debug tijd beheer"""
|
|
global debug_time_offset, debug_mode_active
|
|
|
|
if flask_request.method == 'POST':
|
|
# Check of debug mode is ingeschakeld voor POST requests
|
|
settings = load_settings()
|
|
if not settings.get('debug_mode', False):
|
|
return jsonify({'success': False, 'error': 'Debug mode is niet ingeschakeld'}), 403
|
|
|
|
try:
|
|
data = flask_request.get_json()
|
|
action = data.get('action')
|
|
|
|
if action == 'set_offset':
|
|
debug_time_offset = data.get('offset', 0)
|
|
debug_mode_active = True
|
|
return jsonify({
|
|
'success': True,
|
|
'message': f'Debug tijd offset ingesteld op {debug_time_offset} seconden',
|
|
'offset': debug_time_offset,
|
|
'debug_active': debug_mode_active
|
|
})
|
|
|
|
elif action == 'reset':
|
|
debug_time_offset = 0
|
|
debug_mode_active = False
|
|
return jsonify({
|
|
'success': True,
|
|
'message': 'Debug tijd gereset naar echte tijd',
|
|
'offset': debug_time_offset,
|
|
'debug_active': debug_mode_active
|
|
})
|
|
|
|
elif action == 'adjust':
|
|
adjustment = data.get('seconds', 0)
|
|
debug_time_offset += adjustment
|
|
debug_mode_active = True
|
|
return jsonify({
|
|
'success': True,
|
|
'message': f'Debug tijd aangepast met {adjustment} seconden',
|
|
'offset': debug_time_offset,
|
|
'debug_active': debug_mode_active
|
|
})
|
|
|
|
else:
|
|
return jsonify({'success': False, 'error': 'Onbekende actie'}), 400
|
|
|
|
except Exception as e:
|
|
return jsonify({'success': False, 'error': str(e)}), 500
|
|
|
|
else: # GET request - altijd beschikbaar voor cron script
|
|
from datetime import datetime, timedelta
|
|
|
|
current_time = datetime.now()
|
|
if debug_mode_active:
|
|
current_time += timedelta(seconds=debug_time_offset)
|
|
|
|
return jsonify({
|
|
'success': True,
|
|
'current_time': current_time.strftime('%H:%M:%S'),
|
|
'current_time_display': current_time.strftime('%H:%M'),
|
|
'offset': debug_time_offset,
|
|
'debug_active': debug_mode_active,
|
|
'real_time': datetime.now().strftime('%H:%M:%S')
|
|
})
|
|
|
|
if __name__ == '__main__':
|
|
app.run(host='0.0.0.0', port=80) |