ChroGPS Dash
ChroGPS Dash is a lightweight, high-performance, and mobile-friendly web dashboard for monitoring Stratum 1 NTP servers on Debian 12/13 (and equivalent) 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.
ChroGPS Dash is Free and Open Source Software released under the MIT License.
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/install | sudo bash
Then, simply point your browser to “http://chrogps-dash.local” to access the Dasahboard.1
Updating ChroGPS Dash
Simply run the Quick Installation command! It will instantly
update your dashboard, skipping parts that are not necessary. All of your
custom settings are retained when updating ChroGPS Dash
CHECK_UPDATES to false.
Screenshots
Main Dashboard
Helpful Modals
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.
- Bonus “Terminal” theme to mimic a Terminal User Interface.
- 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 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 (Active 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 active 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.
- Clock Sync Health Monitor: Bridging the gap between signal input and system output, this feature visualizes the actual timekeeping performance of the Chrony daemon. It answers the critical question: “The signal is good, but is the server keeping time?”
- Logarithmic Precision Score: Unlike linear percentages, this score uses a tiered logarithmic scale to represent the orders of magnitude involved in precision timekeeping (from nanoseconds to milliseconds).
- Performance Tiers:
- Perfect (100%): Offset < 1 µs. Indicates Hardware PPS precision.
- Excellent (90–95%): Offset < 10–100 µs. Well-tuned local GPS refclock.
- Good (80%): Offset < 1 ms. High-quality LAN synchronization.
- Marginal (60%): Offset < 10 ms. Standard WAN/Internet NTP performance.
- Poor (< 40%): Offset > 100 ms. Indicates significant drift, latency, or configuration issues.
- 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.
- GNSS Receiver Compatibility: If GPSd supports the receiver, so does ChroGPS Dash! See the ChroGPS Dash GNSS Compatibility Guide for detailed information.
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 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 Active” satellite graph and the underlying logging mechanism.false: completely hides the chart from the dashboard and stops the script from writing to thesat_counts.datafile.
- 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.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- Masks the last two octets of IPv4 (
1.2.*.*) and last 5 hextets of IPv6 (2001:db8:1:*:*:*:*:*)
- Masks the last two octets of IPv4 (
false: Displays full IP addresses.
- Note: This setting only affects the display in the dashboard modal; the underlying Chrony logs remain untouched.
SHOW_CLIENT_HOSTNAMES
- Default:
false - Description: Controls hostname resolution in the Client Monitor list.
- Function:
true: The dashboard will attempt to resolve and display hostnames for connected clients.- Note: This requires server-side DNS resolution and may significantly slow down the loading of the client list.
false: Displays raw IP addresses only (Faster performance).
Default Settings Layout
Here is the default setting file layout (/var/www/chrogps-dash/cgpsd-settings.php) as shipped on a new installation.
<?php
// --- OPTIONAL CONFIGURATION ---
// 1. CHECK FOR UPDATES (True/False)
// Set to false to disable daily outgoing calls to the repo API,
// and will disable update notifications in the footer.
$CHECK_UPDATES = true;
// 2. SATELLITE HISTORY (True/False)
// Enable the Seen vs Active satellite graph and rolling log.
$ENABLE_SAT_HISTORY = true;
// 3. DISPLAY RESOLUTION (Sampling Interval in Seconds)
// 60 = Plot one point every minute. 0 = Plot all points.
$GRAPH_SAMPLE_SEC = 30;
// 4. CLIENT MONITOR (True/False)
// Enable the "Clients" button to view active NTP connections.
// (Requires 'clientlog' in chrony.conf and sudo permissions)
$ENABLE_CLIENTS = true;
// 5. PRIVACY: MASK IP ADDRESSES (True/False)
// Masks the last two octets of IPv4 (1.2.*.*) and last 5 hextets of IPv6 (2001:db8:1:*:*:*:*:*).
$MASK_CLIENT_IPS = true;
// 6. CLIENT LIST HOSTNAMES (True/False)
// If true, attempts to resolve hostnames. (Default: false)
// Note: This may be slower and requires DNS resolution on the server.
$SHOW_CLIENT_HOSTNAMES = false;
// --- END OPTIONAL CONFIGURATION ---
Satellite History Charting & Logging
The Satellite Visibility History chart (optional) tracks the number of satellites Seen vs. Active 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 (does not need to be
root):crontab -e -
Add these lines 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/www/chrogps-dash/sat_counts.data - 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.
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).
Manual Installation
See Installing ChroGPS Dash Manually
Contributing
Feel free to fork this project and submit Pull Requests. See the ChroGPS Dash Contributing Guide.
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 ntpd-rs or timesyncd or openntpd etc.)?”
- A: God no. And it never will. Chrony is superior in every way. Just…use…Chrony.
- Q: “Can I install ChroGPS Dash on WPSD??”
- A: No!!! 🛑 🚫
Look, I know I wrote both of these apps, but they were (deliberately) designed to not play nice together. WPSD is a managed ‘appliance’ — it likes its designs/setups exactly how they are.
Install ChroGPS Dash on a fresh or other existing, non-WPSD Linux instance so that WPSD remains happy and functional.
For the love of God…Just leave your WPSD installation alone and let it be. 🤦
Uninstalling
If you used the Quick Installer, it’s simple…Just run the following command:
curl -sSL https://w0chp.radio/ChroGPS-Dash/install | sudo bash -s -- uninstall
Rationale for the Creation of ChroGPS Dash
I wanted a fast, comprehensive, modern and lightweight webpage/dashboard to monitor the overall health and operating status of my Stratum 1 Chrony/GPS NTP servers, but I could not find anything that met my exact needs/requirements; so I created ChroGPS Dash! 😁
I also wanted web app that was 100% self-contained and extremely portable; 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!
Then I decided to share ChroGPS Dash with others; a program that is easy to deploy as well as contribute to; especially nerds, schools, clubs, etc. and other STEM-like programs and organizations.
And let’s be honest…Data Is Beautiful. 😍 📊
We, as hackers, create things ourselves to scratch our own personal itches. This software does just that…and I hope it scratches yours, too – ergo, I present to you ChroGPS Dash! 💪
Software License
ChroGPS Dash is distributed under the MIT License.
-
The ChroGPS Dash installer configures ZeroConf/mDNS so that the dashboard can be easily accessed 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/install | sudo bash -s -- -npChroGPS Dash will then be installed and configured without the ZeroConf/mDNS (
avahi) daemon/configuration. ⤴