ShackClock 1.0 An All-in-One Ham Radio Shack Dashboard

 


ShackClock 1.0 An All-in-One Ham Radio Shack Dashboard

I've always liked the idea behind HamClock and the various commercial world-map displays aimed at ham radio operators. Put a big screen in the shack, leave it running and at a glance you can see propagation information, DX activity, satellites, weather, UTC and whatever else is useful that day.

But I also wanted something I could customize. Every product I looked at had different features and displays but I wanted something that could do everything I wanted on one screen, so I wrote what I call ShackClock.

ShackClock is a full screen amateur radio dashboard I built around Node-RED, Leaflet, Docker and a collection of public APIs. It will run on a Mac, Raspberry Pi or pretty much anything that can run Docker and a web browser. It is easy to setup and does not require a dedicated computer.

One Screen Instead of Ten Browser Tabs

At the center of ShackClock is a full-screen satellite map.

The base map comes from Esri and then ShackClock layers other information on top of it. Those layers can be independently enabled or disabled, so the display can be fairly clean or completely covered with information depending on what I'm interested in at the moment.

Current layers include:

• animated weather radar

• clouds

• lightning

• earthquakes

• worldwide aircraft

• public aircraft-carrier status

• greyline

• aurora

• DX spots

• POTA spots

• PSKReporter paths

• active amateur satellites

• ISS position, track and footprint

• my QTH

• map labels

The dashboard is intended to run full-screen on something like a 40- to 55-inch TV in the shack, although there's nothing preventing you from running it on a laptop or desktop browser.

DX Cluster and POTA Activity

Obviously, if this was going to sit in a ham shack, I wanted actual radio activity on the screen.

ShackClock connects to the W3LPL DX Cluster (or any cluster you choose in the settings) and plots spots on the map.

There's also a Ham Activity section showing the latest ten DX spots. I deliberately kept the DX display relatively compact just frequency and mode rather than trying to cram every possible data point into a small area.

POTA is handled in the same way with POTA spots plotted geographically and the latest ten are also displayed in the activity panel.

I also added PSKReporter paths. Watching the data appear as I transmit in CW or FT8 let’s me see my signal propagation in real time. 

Satellites But Only the Ones Actually in Operation

One thing I didn't like about simply loading an amateur-radio satellite TLE file was that it could put a lot of satellites on the map that weren't particularly useful at that moment.

So ShackClock now combines orbital data with the AMSAT Satellite Status API.

Instead of blindly displaying everything classified as an amateur satellite, ShackClock looks for satellites that have recently been reported as:

Heard

Crew Active

By default, it looks at the previous 24 hours. 

That gives me an ACTIVE HAM SATS layer rather than just an enormous satellite catalog.

The system then obtains orbital elements from AMSAT's current nasabare.txt and dailytle.txt feeds. It merges those lists, matches them against the recently active satellites, and only sends the useful subset to the browser.

There's also some name normalization going on behind the scenes. For example, AMSAT may report:

AO-7_[U/v]

AO-7_[V/a]

while the orbital data identifies the spacecraft as:

AO-07

ShackClock recognizes those as the same satellite. 

The satellites themselves now appear on the map with an icon:

🛰

instead of another little colored dot.

If an active satellite doesn't have matching orbital data, ShackClock doesn't invent a location. It lists it as unmatched in the diagnostic API instead.

Tracking the ISS

The ISS gets special treatment and ShackClock displays:

• latitude and longitude

• altitude

• distance from my QTH

• footprint

• ground track

• TLE/source age

The orbital elements are cached, so opening or refreshing the dashboard doesn't continually hammer the upstream provider. If the source temporarily goes down, the system can continue using the last known good orbital data.

There's also a diagnostic URL:

curl -s http://localhost:4040/api/iss/state | python3 -m json.tool

One of the design philosophies I've increasingly used with ShackClock is this:

Don't make the browser responsible for talking to every service on the Internet.

Have the server collect, normalize and cache the data, then let the browser display it.

That's proven to be much more reliable.


Worldwide Aircraft




Then I decided it would be interesting to put airplanes on the map and that turned into three possible aircraft sources.

Worldwide mode uses OpenSky.

Nearby mode can use ADSB.lol or ADSB.fi around the station location.

Local mode can use your own dump1090/readsb aircraft.json.

For worldwide mode, ShackClock periodically downloads a global aircraft snapshot and caches it locally. The browser therefore doesn't make a new OpenSky request every time the page reloads.

There can be thousands of aircraft in a worldwide snapshot, so rendering each one as an individual HTML map marker wasn't a great idea, particularly if I eventually wanted the same display to run nicely on a Raspberry Pi.

Instead, worldwide aircraft are drawn onto a single canvas layer.

And yes, I replaced the original dots with little directional airplane symbols.


The Carrier Layer


This one started mostly because I thought it would be interesting and I saw someone else doing it.

ShackClock has a public U.S. aircraft carrier status layer covering the 11 commissioned carriers.

There are two intentionally different kinds of markers:

DEPLOYED / UNDERWAY represents a coarse operating region based on publicly reported USNI Fleet Tracker information.

HOMEPORT / REFERENCE represents public homeport, training or maintenance information for carriers that aren't shown as deployed.

Maintenance states such as RCOH can be displayed separately as well.

It's important to understand what this layer isn't. It is not an attempt to create a live tactical ship-tracking system. The deployed locations are deliberately coarse public regions. The other locations are references such as public homeports or maintenance facilities.

USNI also sometimes blocks automated access, so ShackClock has a bundled public snapshot it can fall back to rather than leaving the layer empty.


Weather and Space Weather



The weather side has also become fairly extensive.

ShackClock can get current conditions from OpenWeather or you can connect your own local station using WeeWX/MQTT.

Map overlays include RainViewer animated radar, OpenWeather cloud coverage and an optional lightning GeoJSON source.

There's also an NWS forecast.

On the ham-radio side, NOAA/SWPC provides the space-weather information:

• solar flux
• Kp
• R/S/G scales
• HF conditions
• OVATION aurora data

So in addition to seeing DX spots appearing geographically, I can look at the same screen and see what propagation conditions are doing. 

And of course there's a greyline overlay. Because a ham-radio world map without greyline just feels wrong.


Earthquakes As Well




USGS real-time GeoJSON provides a selectable earthquake layer.

I can control things such as minimum magnitude and maximum age:

EARTHQUAKE_MIN_MAG
EARTHQUAKE_MAX_AGE_HOURS

I'm not going to pretend earthquakes are an essential amateur-radio feature.

I just like seeing info on them and that's one of the advantages of building your own dashboard.


Clocks Everywhere


The bottom of the display has local time and UTC plus configurable world clocks.

ShackClock supports up to eight city clocks.

The default set is:

Tokyo
Sydney
London
New York
Denver
Chicago

That still leaves two slots open.

The clocks are sorted according to their local date and time rather than simply appearing in configuration order. 

For DXing, contests and just generally figuring out whether people are at work or sleeping, having multiple time zones permanently visible has been surprisingly useful.


I Wanted This to Be Easy to Deploy


One of my priorities for the 1.0 release was getting away from a pile of individually installed dependencies and complicated setup instructions.

ShackClock is now packaged as an all-in-one Docker application. Node-RED, the ShackClock web interface, and the supporting helper processes all run together inside Docker.

Download ShackClock from GitHub

The easiest way to install ShackClock is to download the packaged release from GitHub.

Go to the ShackClock repository:

https://github.com/n3bkv/node-red-shackclock

Click Releases on the right side of the repository page and select the v1.0.0 release.

Under Assets, right click to download:

node-red-shackclock-v1.0.0.zip

Save the ZIP file somewhere convenient, such as your Downloads folder.

You can also download the repository source using Git:

git clone https://github.com/n3bkv/node-red-shackclock.git
cd node-red-shackclock

For most users, however, I recommend downloading the packaged release ZIP because it contains the files intended to work together for that release.


To Run ShackClock on a Mac


First install Docker Desktop if you don't already have it.

Then open Terminal and go to the directory containing the downloaded ZIP file. For example:

cd ~/Downloads

Unzip ShackClock:

unzip node-red-shackclock-v1.0.0.zip

Enter the new directory:

cd node-red-shackclock-v1.0.0

Create your local configuration file from the supplied example:

cp .env.example .env

Edit .env and enter your station information:

nano .env

At a minimum, set your call sign, station name, latitude, longitude, elevation and timezone.

For example:

SHACKCLOCK_PORT=4040
SHACKCLOCK_DATA_VOLUME=shackclock-data

TZ=America/Los_Angeles
STATION_CALL=YOURCALL
STATION_NAME=Your Call ShackClock
STATION_LAT=YOUR_LATITUDE
STATION_LON=YOUR_LONGITUDE
STATION_ELEV_M=YOUR_ELEVATION

The .env.example file documents the other optional settings, including weather and lightning data sources.

Now build and start ShackClock:

docker compose up -d --build

Docker will download the required base images, build the ShackClock container and start the application.

You can confirm that it is running with:

docker compose ps

Then open a browser and go to:

http://localhost:4040/

That's ShackClock. And once it is running you can change parameters in the settings screen by choosing the settings button on the right hand side of the screen.  So you don’t need to go into the .env file if you don’t want to.

The Node-RED editor is available separately at:

http://localhost:4040/admin


Running ShackClock on a Raspberry Pi


The same basic Docker deployment works on a Raspberry Pi running Docker.
Download or copy the ShackClock release to the Pi, unzip it, create your .env file, and start it:

unzip node-red-shackclock-v1.0.0.zip

cd node-red-shackclock-v1.0.0

cp .env.example .env

nano .env

docker compose up -d --build

Once the container is running, ShackClock is available at:

http://localhost:4040/

If you're accessing it from another computer on your network, replace localhost with the IP address of the Raspberry Pi:

http://PI-IP-ADDRESS:4040/

For example:

http://192.168.1.50:4040/


Turn a Raspberry Pi Into a ShackClock Appliance


For a dedicated monitor or TV connected directly to the Raspberry Pi, Chromium can automatically display ShackClock full-screen in kiosk mode:

chromium \
  --kiosk \
  --noerrdialogs \
  --disable-infobars \
  http://localhost:4040/

That effectively turns the Raspberry Pi into a dedicated ShackClock appliance.

There is no separate Node-RED installation, web server installation, or collection of helper scripts to configure on the host. Docker contains the application environment, while your .env file and Docker volume hold the configuration and persistent ShackClock data.

To stop ShackClock:

docker compose down

To start it again:

docker compose up -d

And to see what ShackClock is doing:

docker compose logs -f

The goal with the 1.0 release was simple: download it, configure your station, run Docker Compose, and put ShackClock on the screen.


Changing the Port

Version 1.0 also makes the external Docker port configurable.

The default remains:

4040

but it can be changed in .env:

SHACKCLOCK_PORT=8080

Then the dashboard becomes:

http://localhost:8080/

Node-RED itself continues to listen on port 4040 inside the container. Only the host-side Docker mapping changes.

That makes it much easier to install ShackClock alongside other services on the same Raspberry Pi or server.


Keeping the Configuration





All of the normal settings are stored in a Docker volume.

The primary configuration file is:

/data/shackclock-settings.json

and settings can be changed from the SETTINGS button directly in the dashboard. 

The Docker volume itself can also be selected:

SHACKCLOCK_DATA_VOLUME=shackclock-data

So the container is disposable while the configuration isn't.

That is exactly how I want something like this to behave. Rebuild it, replace it, upgrade it but the station configuration remains.


A Few Useful Diagnostic URLs


Because this has grown into quite a collection of moving parts, I've added APIs that make troubleshooting much easier.

Some of the useful ones are:

/api/health
/api/config
/api/station

/api/dx
/api/pota
/api/psk

/api/amateur/tle
/api/amateur/status

/api/iss/state
/api/iss/tle

/api/aircraft
/api/carriers

/api/earthquakes

/api/space/kp
/api/space/flux
/api/space/scales
/api/space/aurora

The full list is documented in the project README. 

For example:

curl -s http://localhost:4040/api/amateur/status | \
python3 -m json.tool

lets me see exactly what AMSAT is reporting, which orbital source ShackClock is using, how many active satellites matched and which ones didn't.

Likewise:

curl -s http://localhost:4040/api/carriers | \
python3 -m json.tool

shows what's actually feeding the carrier layer.

That has made debugging external API problems considerably easier than trying to figure out why some symbol isn't appearing on the map.


Why Node-RED?


People sometimes ask why I use Node-RED for projects like this.

Part of the answer is that it makes experimentation extremely fast.

I can have conventional JavaScript helpers doing the heavier work, Node-RED handling APIs and orchestration and a completely custom HTML/JavaScript interface on top of Leaflet.

It's a nice combination.

And unlike using the normal Node-RED dashboard for everything, ShackClock is its own dedicated web application.

If I give somebody the ShackClock URL, they get ShackClock.

They aren't dropped into some generic collection of unrelated Node-RED dashboards running on the same machine.


What v1.0 Means


Calling this version 1.0 doesn't mean I'm finished with it.

That's probably impossible.

It means I've reached the point where there's a reasonably coherent baseline:

Radio
Weather
Space Weather
Satellites
ISS
POTA
DX
PSKReporter
Aircraft
Carriers
Earthquakes
Greyline
World Clocks

all running together in one Dockerized application.

The current data sources include Esri, RainViewer, OpenWeather, NWS, NOAA SWPC, USGS, W3LPL, POTA, PSKReporter, AMSAT, WhereTheISS.at, OpenSky, ADSB.lol/ADSB.fi and USNI, with optional local data from WeeWX and dump1090/readsb.

Most of these services provide public data feeds that ShackClock can use without requiring an account or API key. For the current ShackClock 1.0 release, OpenWeather is the only service for which you need to create an account and obtain an API key.

Create a free OpenWeather account and API key here:

OpenWeather:
https://openweathermap.org/api

After creating your account, OpenWeather provides an API key that can be entered in the ShackClock Settings page. The free tier is more than adequate for normal ShackClock use.

The other built-in Internet data sources are accessed through their public APIs or data feeds and do not require you to create accounts or enter credentials into ShackClock. For example, RainViewer's public radar API does not require registration or an API key.

If you configure optional local sources such as WeeWX or dump1090/readsb, no Internet API account is required; you simply provide ShackClock with the URL of the local data source.

So, in most cases, getting ShackClock online is simply a matter of entering your station information and adding an OpenWeather API key.


What's Next?


Now that I have a 1.0 baseline, I'm much more interested in adding features without breaking the rest of the display.

A few areas I want to continue experimenting with include better satellite presentation, more useful propagation visualization, additional local-station integrations, and making the large-screen interface even easier to read from across the shack.

That's part of the fun of this project.

There are plenty of excellent prebuilt ham-radio displays available but ShackClock exists because I wanted one I could take apart. If I don't like the way a layer works, I can rewrite it. If I want another data source, I can add it. If an API disappears, I can replace it. 

73,
Dave

Comments

Popular posts from this blog

How to Put Your AllStar Node on 44Net Connect

Why You Might Want To Set Up Your Raspberry Pi Internet Web Server on 44Net

How To Set Up Your Own Remote Station

Build a Central N3FJP Field Day Log Server With Local DHCP and GPS Time

Building a Secure Web Portal on 44Net Without VPN Headaches

How To Get Precise Time Outside Your Shack

Getting WaveNode Power Meter Data Into Node-RED

Turning Your Starlink Mini into a Real Telemetry Device - How to bridge Starlink Mini into MQTT and Node-RED for real-time monitoring and automation

A Non-Programmers Guide on How To Use AI to Write Your Own Custom Ham Radio Computer Applications

Ham RSS News Feeds

Amateur Radio Daily

ARRL News

Zero Retries