This project not only calculates and plays the five daily adhans on a Raspberry Pi via cron, but also drives a full‑screen display showing:
- Today’s prayer times and live countdown
- Next Jumʿah Khateeb schedule (automatically scraped each night)
- Raspberry Pi running Raspberry Pi OS (formerly Raspbian)
- Pi 3/4/400 or newer recommended (for Puppeteer). Avoid Pi Zero if new.
- HDMI output to a display or TV.
- Speakers (wired aux recommended; Bluetooth has disconnect quirks).
- Internet connection (for initial setup and nightly scraping).
- Git, Node.js, Python 3 installed on the Pi:
sudo apt update sudo apt install -y git nodejs npm python3 python3-pip chromium-browser xdotool
- Python packages (in your project folder):
cd ~/adhan-display pip3 install requests beautifulsoup4
- Node packages (for the Jumʿah scraper):
cd ~/adhan-display npm install puppeteer
cd ~
git clone https://github.com/SyButter/rasppi-adhan.git adhan-display
cd adhan-displayRun the timer‑setup script once with your coordinates and preferred method:
python3 updateAzaanTimers.py --lat <YOUR_LATITUDE> --lon <YOUR_LONGITUDE> --method ISNA # or MWL, Egypt, Karachi, etc.This will:
- Write your
lat,lon,method(and optional volumes) intosettings.ini. - Calculate today’s prayer times and install cron jobs to play the Adhan audio.
- Schedule itself to re‑run nightly at 1 AM and truncate logs monthly.
Tip: Use
crontab -lto verify your jobs. Logs are in~/adhan-display/adhan.log.
Edit settings.ini:
[FRIDAY]
playSurahBaqarah = True
surahVolume = 0All files for the dashboard live in ~/adhan-display:
adhan-display/
├── index.html
├── style.css
├── script.js
├── prayTimes.js # PrayTimes.js v2 from praytimes.org
├── schedule.json # auto‑generated by scraper
├── scrape_jummah_schedule.js # Node scraper
└── prayerTimes.json # (optional) from updateDisplayData.py
wget https://praytimes.org/code/v2/js/PrayTimes.js -O prayTimes.js<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prayer Times & Jummah</title>
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Prayer Times</h1>
<div id="date"></div>
<ul id="times"></ul>
<div id="next"></div>
<section id="jummah-schedule">
<h2>Next Jummah Khateeb</h2>
<table>
<thead><tr><th>Date</th><th>First</th><th>Second</th></tr></thead>
<tbody></tbody>
</table>
</section>
<script src="prayTimes.js"></script>
<script src="script.js"></script>
</body>
</html>body {
background:#111; color:#ccc; font-family:sans-serif;
display:flex; flex-direction:column; align-items:center;
}
h1 { margin:1rem; }
ul#times { list-style:none; width:300px; }
ul#times li { display:flex; justify-content:space-between; padding:.5rem; border-bottom:1px solid #444; }
#next { margin:1rem; font-size:1.2rem; }
#jummah-schedule {
margin:2rem auto; padding:1rem; background:#222; border-radius:6px;
}
#jummah-schedule h2 { text-align:center; margin-bottom:1rem; }
#jummah-schedule table { width:100%; border-collapse:collapse; }
#jummah-schedule th, #jummah-schedule td { padding:.5rem; border:1px solid #333; text-align:center; }
#jummah-schedule th { background:#333; color:#eee; }// CONFIG
const pt = new PrayTimes('ISNA'); // adjust or load from settings.ini
// helpers
function pad(n){return n<10?'0'+n:n;}
function format12(t){let [h,m]=t.split(':').map(Number),amp=h>=12?'PM':'AM';h=(h%12)||12;return `${h}:${pad(m)} ${amp}`;}
// render prayer times & countdown...
function renderTimes(){ /* your existing code */ }
// render next Jummah
async function renderNextJummah(){
const data = await fetch('schedule.json').then(r=>r.json());
const [next] = data;
if(!next) return;
document.querySelector('#jummah-schedule tbody').innerHTML =
`<tr><td>${next.date}</td><td>${next.first}</td><td>${next.second}</td></tr>`;
}
// schedule 2 AM fetch
function scheduleDaily(fn,h){
const now=new Date(), then=new Date(now.getFullYear(),now.getMonth(),now.getDate(),h);
if(then<=now) then.setDate(then.getDate()+1);
setTimeout(()=>{fn();setInterval(fn,86400000);},then-now);
}
// initial + intervals
renderTimes(); renderNextJummah();
setInterval(renderTimes,60000);
scheduleDaily(renderNextJummah,2);Uses Puppeteer to load the site, extract #schedule-table rows, filter for upcoming Fridays, write schedule.json.
Run manually or via cron:
node scrape_jummah_schedule.jscrontab -e
# Add:
0 2 * * * cd ~/adhan-display && /usr/bin/node scrape_jummah_schedule.js >> scrape.log 2>&1sudo tee /etc/systemd/system/adhan-display.service <<EOF
[Unit]
Description=Adhan Dashboard HTTP Server
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/adhan-display
ExecStart=/usr/bin/python3 -m http.server 8000 --bind 0.0.0.0
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable adhan-display
sudo systemctl start adhan-displaymkdir -p /home/pi/.config/lxsession/LXDE-pi
tee /home/pi/.config/lxsession/LXDE-pi/autostart <<EOF
@xset s off
@xset -dpms
@xset s noblank
@bash -c "sleep 10"
@chromium-browser --noerrdialogs --disable-infobars --kiosk http://localhost:8000
EOF
chown -R pi:pi /home/pi/.configSet–and–forget – your Pi will ring adhans, scrape upcoming Jumʿah, and display both on screen every day!