ChroGPS Dash
ChroGPS Dash is a lightweight, high-performance, and mobile-friendly web dashboard for monitoring Stratum 1 NTP servers on Debian 12/13 which run Chrony and GPSd. It provides real-time diagnostics for Chrony and GPSd, featuring a live satellite skyview, SNR telemetry, precision timing metrics, and more.
Table of Contents:
Quick Installation (recommended)
On a Debian-based instance, run the following command to install ChroGPS Dash:
curl -sSL https://w0chp.radio/ChroGPS-Dash.sh | sudo bash
Then, simply point your browser to “http://chrogps-dash.local” to access the Dasahboard.1
if you already have Nginx and/or PHP-FPM installed, it will skip those parts.
Updating ChroGPS Dash
Simply run the Quick Installation command! It will instantly update your dashboard, skipping parts that are not necessary.
CHECK_UPDATES to false.
Screenshots
| Dark Theme | Light Theme |
|---|---|
|
|
| Client Connections Modal | Legend / Glossary Modal |
|
|
Features
- Mission Control Layout:
- Real-Time Telemetry: Live updates for Chrony sources, system tracking, and GPS satellite status.
- Interactive Skyview: A polar plot of the satellite constellation with instant CSS-driven popups for PRN, SNR, and constellation type.
- Precision Diagnostics: Displays TDOP (Time Dilution of Precision), 3D Fix status, hardware serial paths, and leap second status.
- Client Monitor: An on-demand, inspector for connected NTP clients. View IP addresses, packet hits/drops, and “Last Seen” intervals to identify heavy users or abusers.
- Signal Spectrum Analysis: A dynamic SNR Histogram providing a visual equalizer-style view of satellite signal strength.
- Platform Diagnostics: Expanded Node Vitals displaying OS version, Kernel, and Architecture details.
- Modern UI/UX:
- Dark/Light Modes: Respects system settings with a manual toggle.
- Customizable Font Size: Small, Medium, and Large scaling options saved to browser localstorage.
- Instant Tooltips: Instant hover popups for important table headers & elements and data points — no browser delay.
- Configurable data refresh intervals.
- Tabbed Historical Data: Consolidated historical graphs (Tracking, Statistics, Measurements) into a single card with persistent navigation and an “All Graphs” comparison mode.
- Dynamic History Slider: A responsive slider to adjust the graph time window from 1 to 12 hours, saved to your browser preferences.
- Lightweight Backend: 100% Self-Contained… Pure PHP and Javascript with zero external dependencies (no Google Fonts, no heavy libraries and no frameworks).
- Just one simple file!
- Universal Compatibility: Designed for Debian 12 (Bookworm) and 13 (Trixie), including RaspberryPi OS and Armbian. See Supported OS Derivatives below.
- Native SVG Charts: Server-side generated graphs for Tracking (Offset vs Freq), Statistics (Est Offset vs Std Dev), Measurements (Offset vs Peer Delay) and Satellite Visibility History (Used vs. Seen).
- Interactive Tooltips: Mouseover any data point on the charts for instant, precise values.
- Zero Client-Side Bloat: No external charting libraries (like Chart.js) are used.
- Signal Integrity Monitor: ChroGPS Dash introduces a real-time Signal Integrity Monitor that goes beyond simple “Fix/No-Fix” status. This feature analyzes the signal quality (SNR) of currently used satellites to generate a health score for your antenna installation…
- Signal Health Score: A visual 0–100% progress bar indicates the overall quality of your GPS lock.
- Perfect (90%+): Average SNR > 40 dBHz. Ideal antenna placement with clear sky view.
- Good (70-89%): Average SNR > 34 dBHz. Standard operation with solid lock.
- Marginal (50-69%): Average SNR > 29 dBHz. Functional, but may have partial obstructions or minor cable loss.
- Poor (< 50%): Average SNR < 29 dBHz. Indicates severe antenna obstruction, cable damage, or local RF interference.
- Smart Filtering: The algorithm dynamically filters out “visible but unused” satellites, ensuring low-horizon satellites don’t unfairly drag down your system’s health score.
- Visual Diagnostics: The color-coded bar (Green/Blue/Amber/Red) allows operators to instantly assess antenna health from across the room without reading raw data tables.
- Signal Health Score: A visual 0–100% progress bar indicates the overall quality of your GPS lock.
- Solar Position & Interference Tracking: Includes a professional-grade solar tracking engine that overlays the sun’s current position onto the Satellite Skyview plot. This feature, typically found only in high-end GNSS timing equipment, allows operators to visualize potential Sun Outages (Solar Transits) in real-time.
- Solar Radio Interference: The sun acts as a broadband RF noise generator. When it aligns directly behind a GPS satellite (azimuth/elevation overlap), thermal noise can overpower the weak satellite signal, causing sharp drops in SNR or complete loss of lock.
- Visual Diagnostics: Instantly distinguish between antenna hardware failures and natural solar interference events during the spring and autumn equinoxes.
- Zero-Dependency Implementation: The solar tracking engine is written entirely in lightweight, client-side JavaScript using the Astronomical Almanac’s Low-Precision Algorithm. It requires no external libraries, and no internet connection to function.
Optional Settings
The dashboard configuration is managed via a dedicated settings file located at /var/www/chrogps-dash/cgpsd-settings.php.
To customize the dashboard behavior, simply edit this file:
sudo nano /var/www/chrogps-dash/cgpsd-settings.php
Settings & Their Descriptions
Below are the user-configurable dashboard options/settings and their descriptions:
CHECK_UPDATES
- Default:
true - Description: Toggles the automatic daily update check. If an update is available, a notification is displayed in the dashboard footer.
- Function:
true: The dashboard will make a single outgoing call once every 24 hours to the repository API to check for a newer version. If found, an “Update” badge appears in the footer.false: Disables all outgoing network connections from the dashboard script and disables update notifications.
ENABLE_SAT_HISTORY
- Default:
false - Description: Controls the “Satellite Visibility History” feature.
- Function:
true: Enables the “Seen vs Used” satellite graph and the underlying logging mechanism.false: completely hides the chart from the dashboard and stops the script from writing to thesat_counts.logfile.
- More Info: A descriptive section about how this works is here.
GRAPH_SAMPLE_SEC
- Default:
30 - Description: Controls the resolution of the data points plotted on the graphs.
- Function: This setting acts as a “sampling interval” in seconds.
- If set to
30, the graph will plot one data point for every 30-second block of time found in the logs. - If set to
0, the dashboard will attempt to plot every single line from the log file.
- If set to
- Usage: Increasing this value smoothes out the graph and improves performance on slower devices. Setting it to
0provides maximum detail but may look cluttered or load slower.
ENABLE_CLIENTS
- Default:
false - Description: Toggles the “Client Monitor” feature.
- Function:
true: Adds a "🌐 Clients" button to the dashboard header. When clicked, it pauses the live dashboard and loads a snapshot of active NTP connections (viachronyc -n clients).false: Hides the button and disables the backend PHP logic for querying client data.
- Requirements: This feature requires the
clientlogdirective inchrony.confand specific sudo permissions.-
TipThe Quick Installer automatically configures these requirements for you.
-
MASK_CLIENT_IPS
- Default:
false - Description: Controls the privacy masking of client IP addresses in the Client Monitor.
- Function:
true: Applies a privacy mask to all displayed IP addresses.- IPv4: Masks the last three octets (e.g.,
1.2.3.4becomes1.*.*.*). - IPv6: Masks the last 6 hextets, preserving only the prefix (e.g.,
2001:db8:1:2:3:4:5:6becomes2001:db8:*:*:*:*:*:*).
- IPv4: Masks the last three octets (e.g.,
false: Displays full IP addresses.
- Note: This setting only affects the display in the dashboard modal; the underlying Chrony logs remain untouched.
Satellite History Charting & Logging
The Satellite Visibility History chart (optional) tracks the number of satellites Seen vs. Used over time. This is useful for analyzing antenna placement, sky obstructions, and constellation coverage.
How It Works (The “Observer Effect”)
By default, this dashboard only logs satellite data while the page is open in a browser.
To keep the application dependency-free and lightweight, the PHP script itself acts as the logger. If no one is viewing the dashboard, the logging function isn’t running, and no satellite counts are recorded. But there is a way(s) to automate the logging/data collection…
Enabling 24/7 Data Collection
To capture a continuous history without keeping a browser tab open, you can set up a simple cron job to “ping” the dashboard in the background.
-
Open your crontab:
crontab -e -
Add a line to fetch the dashboard’s data endpoint every minute:
* * * * * curl -s 'http://localhost/index.php?ajax=1' >/dev/nullTipIf you want higher resolution, such as every 30 seconds, you can use:
* * * * * for i in 0 30; do (sleep $i; curl -s 'http://localhost?ajax=1' >/dev/null) & done -
Save and exit.
Your system will now silently log satellite counts 24/7, ensuring your history graph is always full when you open the dashboard.
Log Management
- File Location:
/var/log/chrony/sat_counts.log - Rotation: The log is self-managing. It uses a Rolling Buffer (15,000 lines) to ensure it never grows indefinitely. Once the limit is reached, the oldest entry is deleted to make room for the new one.
Manual Installation
If you prefer to set things up manually, ensure you have the following:
- Web Server: Nginx or Apache
- PHP: Version 8.2 or newer (with php-json extension enabled)
- System Utilities: sudo (required for executing chronyc commands)
- NTP/GPS: Chrony and GPSd installed and running
Configuration Details
Sudo Permissions
The dashboard requires permission to execute chronyc commands to fetch timing data. The installer adds the following line to /etc/sudoers:
www-data ALL=(ALL) NOPASSWD: /usr/bin/chronyc sources, /usr/bin/chronyc tracking, /usr/bin/chronyc serverstats, /usr/bin/chronyc -n clients
Log File Access
- The charts are generated by parsing raw Chrony logs (tracking.log, statistics.log, measurements.log). The installer:
- Adds the
www-datauser to the_chronygroup. - Sets group-read/write permissions (
g+rw) on the log files in/var/log/chrony. - Configures Chrony to log the data if it’s not enabled.
…So you will need to perform these tasks if you wish to install ChroGPS Dash manually.
GPSD Integration
The dashboard connects to gpsd via a local socket on port 2947. Ensure gpsd is configured to listen on all interfaces or at least localhost.
Requirements
- Operating System: Debian 12/13, RaspberryPi OS, Armbian, or any Debian 12/13-based OS.
- Hardware: Raspberry Pi or similar SBC with a GPS module.
- Software: Chrony, GPSd, Nginz, PHP-FPM.
Supported OS Derivatives
In addition to native Debian 12/13, this dashboard and installer explicitly support the following derivatives:
- Ubuntu: 24.04 LTS (Noble Numbat), 24.10 (Oracular Oriole), and 25.04 (Plucky Puffin).
- Raspberry Pi OS: Versions based on Bookworm or Trixie.
- Armbian: Versions tracking the Debian 12/13 or Ubuntu 24.04+ repositories.
- Linux Mint: 22 (Wilma) and newer (based on the Ubuntu 24.04 package set).
Contributing
Feel free to fork this project and submit Pull Requests. See CONTRIBUTING.md.
Troubleshooting
Dashboard not loading (Nginx “Welcome” Page)
If you see the default “Welcome to nginx!” page after installation, it means the default Nginx configuration is still active and taking priority over ChroGPS Dash.
To resolve this, run the following commands to disable the default site and restart the web server:
sudo rm /etc/nginx/sites-enabled/default && sudo systemctl restart nginx
Empty Charts?
If charts appear but have no data:
- Verify Chrony is logging:
sudo ls -l /var/log/chrony/ - Wait a few minutes for logs to populate.
- Run the installer again to re-apply permission fixes.
Upgraded your OS and now the Dashboard won’t load or throws an error?
Easy…just run the installer command.
Sometimes this will happen due to OSs upgrading the PHP-FPM versions (e.g. Debian 12 uses v8.2 and Debian 13 uses v8.4, and the installer will detect this and fix it for you).
“Cannot create/open log file: …” Message?
You broke something. Simply re-run the installer to fix it.
Support
- Q: “It’s not working, can you help me?”
- A: No.
- Q: “But I used the installer!”
A: It works on my machines.
¯\_(ツ)_/¯This project is a labor of love, not a job. Please consult the Googles, the Linux man pages, or your local wizard for assistance.
In all (kind-of-)seriousnes…
This dashboard is provided with a strict “You Break It, You Fix It” warranty.
I have provided crystal-clear instructions and a magical installer script that does 99% of the work for you. If you still manage to break it, congratulations! You have just discovered a learning opportunity.
- Documentation & Code: Read it again. Slower this time.
- Bugs: If you find a bug, patches are welcome.
- Tech Support: I do not offer tech support. If I did, I would charge a lot more than “Free.”
- Q: “Does ChroGPS Dash support the ntpd daemon from Network Time Foundation/ISC (or ntpsec or timesyncd or openntpd etc.)?”
- A: God no. And it never will. Chrony is superior in every way. Just…use…Chrony.
Uninstalling
If you used the Quick Installer, it’s simple…Just run the following command:
curl -sSL https://w0chp.radio/ChroGPS-Dash.sh | sudo bash -s -- uninstall
Rationale for the Creation of ChroGPS Dash
Originally, I wanted a fast, comprehensive, modern and lightweight, portable & self-contained webpage/dashboard to monitor the health of my Stratum 1 Chrony/GPS NTP servers, and could not find anything that met my exact needs/requirements; so I created ChroGPS Dash! 😁
I also wanted to create something that I could share with others, that is easy to deploy as well as contribute to; especially schools, clubs, etc. and other STEM-like programs and organizations.
And finally, I wanted to create a web app that was 100% self-contained; in that
it requires zero external dependencies.
Admittedly, I have been spoiled by amazing third-party charting, plotting,
CSS, JS and myriad other awesome libraries/frameworks (and still use them); but I
wanted the challenge of creating somethng using native languages & code with
no external libraries/framework dependencies; and in one single file.
Challenge accepted! – I present to you ChroGPS Dash! 💪
And let’s be honest…Data Is Beautiful. 😍 📊
We, as hackers, create things ourselves to scratch our own personal itches. ChroGPS Dash does just that…and I hope it scratches yours, too.
Software License
MIT License: See LICENSE.md
-
The ChroGPS Dash installer configures ZeroConf/mDNS so that the dashboard can be easily accesed from your local network via “
http://chrogps-dash.local”.
If you do not want this functionality, run the installer command with the “no publish” option:⤴curl -sSL https://w0chp.radio/ChroGPS-Dash.sh | sudo bash -s -- -np



