diff --git a/.gitignore b/.gitignore
index 253ea02b..fba7c559 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,6 +67,9 @@ config.local.js
config.local.json
config.json
+# Rig control daemon config (user-specific settings)
+rig-control/rig-config.json
+
# Test files
*.test.js.snap
diff --git a/RIG_CONTROL_COMPARISON.md b/RIG_CONTROL_COMPARISON.md
new file mode 100644
index 00000000..c8c788d0
--- /dev/null
+++ b/RIG_CONTROL_COMPARISON.md
@@ -0,0 +1,292 @@
+# 📻 OpenHamClock Rig Control Solutions — Comparison Guide
+
+OpenHamClock offers **three different solutions** for connecting your radio to the web application. Each serves different use cases and technical requirements.
+
+---
+
+## Quick Decision Guide
+
+**Choose based on your setup:**
+
+| Your Situation | Recommended Solution |
+|----------------|---------------------|
+| 🎯 **I want the simplest setup** | **Rig Listener** — One download, one click |
+| 🔌 **I already use flrig or rigctld** | **Rig Control Daemon** — Works with existing setup |
+| 🌐 **I need a web UI to configure my radio** | **Rig Bridge** — Browser-based configuration |
+| 🏠 **Radio is on a different computer** | **Rig Bridge** or **Rig Control Daemon** — Network accessible |
+| 🐧 **Running on Raspberry Pi** | **Rig Control Daemon** — Lightweight, proven |
+
+---
+
+## Solution Comparison
+
+### 1️⃣ Rig Listener (Newest — Recommended for Most Users)
+
+**What it is:** A standalone executable that connects directly to your radio via USB. No dependencies, no configuration files, no web server.
+
+**Best for:**
+- First-time users who want zero hassle
+- Users who don't need flrig/rigctld for other apps
+- Portable/field operation (single executable)
+
+**Pros:**
+- ✅ **Easiest setup** — Interactive wizard on first run
+- ✅ **Single executable** — No Node.js installation required
+- ✅ **Direct USB connection** — No intermediate software needed
+- ✅ **Remembers settings** — Config saved automatically
+- ✅ **Small footprint** — ~30MB executable
+
+**Cons:**
+- ❌ No web UI for configuration (CLI wizard only)
+- ❌ **USB port exclusivity** — Cannot share radio with other apps simultaneously (WSJT-X, fldigi, etc.)
+- ❌ Must run on same computer as radio USB connection
+
+> [!WARNING]
+> **USB Port Limitation**: When using direct USB connection, only ONE application can access the serial port at a time. If you need to use WSJT-X, fldigi, or other CAT control software alongside OpenHamClock, use **Rig Control Daemon** with flrig/rigctld instead — they can share the radio among multiple applications.
+
+**Supported Radios:**
+- Yaesu (FT-991A, FT-891, FT-710, FT-DX10, FT-817/818)
+- Kenwood (TS-590, TS-890, TS-480, TS-2000)
+- Elecraft (K3, K4, KX3, KX2)
+- Icom (IC-7300, IC-7610, IC-705, IC-9700)
+
+**Setup:**
+```bash
+# Download executable, then:
+./rig-listener-mac-arm64 # Mac
+rig-listener-win-x64.exe # Windows
+./rig-listener-linux-x64 # Linux
+
+# Follow wizard prompts
+# Done! Runs on http://localhost:5555
+```
+
+**When to use:**
+- You want to get started in under 2 minutes
+- You don't use flrig/rigctld for other applications
+- You value simplicity over advanced features
+
+---
+
+### 2️⃣ Rig Bridge (Feature-Rich)
+
+**What it is:** A web-based rig control server with a browser configuration UI. Connects directly to your radio via USB **or** can proxy to flrig/rigctld.
+
+**Best for:**
+- Users who want a web UI to configure their radio
+- Network setups (radio on one computer, OpenHamClock on another)
+- Users who need to switch between radios frequently
+
+**Pros:**
+- ✅ **Web-based configuration** — Configure via browser at http://localhost:5555
+- ✅ **Direct USB or proxy mode** — Works with or without flrig/rigctld
+- ✅ **Network accessible** — Can run on a different computer
+- ✅ **Visual port selection** — See all available COM ports in browser
+- ✅ **Live status display** — Real-time frequency/mode display in web UI
+
+**Cons:**
+- ❌ Requires Node.js (or download pre-built executable)
+- ❌ More complex than Rig Listener
+- ❌ Slightly larger resource footprint
+- ❌ **USB port exclusivity** (when using direct USB mode) — Cannot share radio with other apps
+
+**Supported Radios:**
+- Same as Rig Listener (Yaesu, Kenwood, Icom, Elecraft)
+- **Plus:** Can proxy to flrig/rigctld for any radio they support
+
+**Setup:**
+```bash
+cd rig-bridge
+npm install
+node rig-bridge.js
+
+# Open http://localhost:5555 in browser
+# Select radio type and COM port
+# Click "Save & Connect"
+```
+
+**When to use:**
+- You prefer GUI configuration over CLI
+- You want to access rig control from multiple devices on your network
+- You need to frequently switch between different radios
+- You want a visual confirmation of connection status
+
+---
+
+### 3️⃣ Rig Control Daemon (Original — Most Flexible)
+
+**What it is:** A lightweight Node.js service that acts as a bridge between OpenHamClock and **existing** rig control software (flrig or rigctld).
+
+**Best for:**
+- Users who already run flrig or rigctld for other applications
+- Advanced users who want maximum control via config files
+- Raspberry Pi / headless server deployments
+- Integration with existing HAMlib-based workflows
+
+**Pros:**
+- ✅ **Works with existing setup** — No need to change your current rig control
+- ✅ **Lightweight** — Minimal resource usage
+- ✅ **Flexible configuration** — JSON config file with all options
+- ✅ **Battle-tested** — Original solution, most mature codebase
+- ✅ **Remote access** — Binds to 0.0.0.0 by default for network access
+
+**Cons:**
+- ❌ **Requires flrig or rigctld** — Cannot connect directly to radio
+- ❌ Requires Node.js installation
+- ❌ Manual configuration (edit JSON file)
+- ❌ No built-in web UI
+
+**Supported Backends:**
+- **rigctld** (HAMlib) — Supports 300+ radio models
+- **flrig** — Popular GUI rig control software
+- **mock** — Simulation mode for testing
+
+**Setup:**
+```bash
+cd rig-control
+npm install
+
+# Edit rig-config.json:
+{
+ "radio": {
+ "type": "flrig", // or "rigctld"
+ "host": "127.0.0.1",
+ "port": 12345 // flrig default, rigctld uses 4532
+ }
+}
+
+node rig-daemon.js
+```
+
+**When to use:**
+- You already use flrig or rigctld for WSJT-X, fldigi, etc.
+- You want to share radio control across multiple applications
+- You're running on a Raspberry Pi or headless server
+- You need maximum flexibility and don't mind config files
+
+---
+
+## Technical Comparison
+
+| Feature | Rig Listener | Rig Bridge | Rig Control Daemon |
+|---------|--------------|------------|-------------------|
+| **Direct USB** | ✅ Yes | ✅ Yes | ❌ No (needs flrig/rigctld) |
+| **Web UI** | ❌ No | ✅ Yes | ❌ No |
+| **Standalone Executable** | ✅ Yes | ✅ Yes (optional) | ❌ No |
+| **Requires Node.js** | ❌ No | ❌ No (if using exe) | ✅ Yes |
+| **Config Method** | CLI Wizard | Web UI | JSON File |
+| **Network Access** | ✅ Yes | ✅ Yes | ✅ Yes |
+| **Resource Usage** | Low | Medium | Very Low |
+| **Setup Time** | 2 minutes | 5 minutes | 10 minutes |
+| **Proxy to flrig/rigctld** | ❌ No | ✅ Yes | ✅ Yes (only) |
+
+---
+
+## API Compatibility
+
+**All three solutions expose the same HTTP API**, so OpenHamClock works identically with any of them:
+
+| Endpoint | Method | Description |
+|----------|--------|-------------|
+| `/status` | GET | Current freq, mode, PTT, connection status |
+| `/stream` | GET | Server-Sent Events (SSE) real-time updates |
+| `/freq` | POST | Set frequency: `{ "freq": 14074000 }` |
+| `/mode` | POST | Set mode: `{ "mode": "USB" }` |
+| `/ptt` | POST | Set PTT: `{ "ptt": true }` |
+
+**Additional endpoints (Rig Bridge only):**
+- `/api/ports` — List available serial ports
+- `/api/config` — Get/set configuration via web UI
+
+---
+
+## Migration Guide
+
+### From Rig Control Daemon → Rig Listener
+1. Stop `rig-daemon.js`
+2. Stop `flrig` or `rigctld`
+3. Download and run Rig Listener
+4. Follow the wizard
+5. No changes needed in OpenHamClock settings (same port 5555)
+
+### From Rig Listener → Rig Bridge
+1. Stop Rig Listener
+2. Download/run Rig Bridge
+3. Open http://localhost:5555 and configure
+4. No changes needed in OpenHamClock settings
+
+### From Rig Bridge → Rig Control Daemon
+1. Install and start `flrig` or `rigctld`
+2. Stop Rig Bridge
+3. Configure `rig-control/rig-config.json`
+4. Run `node rig-daemon.js`
+5. No changes needed in OpenHamClock settings
+
+---
+
+## Troubleshooting
+
+### All Solutions
+- **Port 5555 in use:** Another rig control service is running. Stop it first.
+- **OpenHamClock can't connect:** Check firewall, ensure service is running
+- **No frequency updates:** Verify radio is connected and powered on
+
+### Rig Listener / Rig Bridge (Direct USB)
+- **No COM ports found:** Install USB driver (Silicon Labs CP210x for Yaesu)
+- **Port opens but no data:** Baud rate mismatch — check radio's CAT settings
+- **Linux permission denied:** `sudo usermod -a -G dialout $USER` then log out/in
+
+### Rig Control Daemon
+- **Connection refused:** Ensure flrig/rigctld is running first
+- **Wrong port:** Check `rig-config.json` matches flrig/rigctld port
+
+---
+
+## Recommendations by Use Case
+
+### 🏕️ Field Operation / Portable
+**Use Rig Listener** — Single executable, no dependencies, works offline
+
+### 🏠 Home Station (Single Radio)
+**Use Rig Listener** — Simplest setup, direct USB connection
+
+### 🏠 Home Station (Multiple Apps)
+**Use Rig Control Daemon** — Share flrig/rigctld with WSJT-X, fldigi, etc.
+
+> **Why?** Direct USB solutions (Rig Listener/Rig Bridge) lock the serial port exclusively. If you run WSJT-X, fldigi, or other CAT control software, they cannot access the radio simultaneously. The Rig Control Daemon works with flrig/rigctld, which act as a "hub" that multiple applications can connect to at once.
+
+### 🌐 Network Setup (Radio on Different Computer)
+**Use Rig Bridge** — Web UI makes remote configuration easy
+
+### 🐧 Raspberry Pi / Headless Server
+**Use Rig Control Daemon** — Lightweight, proven, easy to automate
+
+### 🔧 Frequent Radio Changes
+**Use Rig Bridge** — Web UI makes switching radios quick
+
+### 🆕 First-Time User
+**Use Rig Listener** — Get running in under 2 minutes
+
+---
+
+## Summary
+
+| Solution | Best For | Complexity | Setup Time |
+|----------|----------|------------|------------|
+| **Rig Listener** | Most users, simplicity | ⭐ Easy | 2 min |
+| **Rig Bridge** | Web UI lovers, network setups | ⭐⭐ Moderate | 5 min |
+| **Rig Control Daemon** | Advanced users, existing flrig/rigctld | ⭐⭐⭐ Advanced | 10 min |
+
+**Still unsure?** Start with **Rig Listener**. You can always switch later — all three use the same API, so OpenHamClock doesn't need reconfiguration.
+
+---
+
+## Getting Help
+
+- **Documentation:** Each solution has its own README in its folder
+- **Issues:** [GitHub Issues](https://github.com/K0CJH/openhamclock/issues)
+- **Community:** Check the OpenHamClock community forums
+
+---
+
+**73 de K0CJH** 📻
diff --git a/rig-control/README.md b/rig-control/README.md
index 69381b77..db4ed106 100644
--- a/rig-control/README.md
+++ b/rig-control/README.md
@@ -27,7 +27,7 @@ npm install
## Configuration
-Configuration is loaded from `rig-config.json`. A default file is provided:
+Configuration is loaded from `rig-config.json`. On first run, this file is automatically created from `rig-config.json.example`:
```json
{
@@ -46,6 +46,8 @@ Configuration is loaded from `rig-config.json`. A default file is provided:
}
```
+**Important:** Your `rig-config.json` customizations are preserved during updates. The file is excluded from git tracking, so your local changes won't be overwritten when pulling new versions.
+
### Configuration Options
- **server.host**: IP to bind to (default 0.0.0.0)
@@ -109,6 +111,23 @@ The daemon listens on port `5555` (configurable) and provides the following endp
- **CORS Errors**: The daemon enables CORS for all origins by default (`*`) to allow local development.
- **Port Conflicts**: If port 5555 is in use, change `server.port` in `rig-config.json`.
+### Mixed Content Issues (HTTPS → HTTP)
+
+**Problem:** If OpenHamClock is accessed via **HTTPS** (e.g., `https://yourdomain.com` or `https://openhamclock.com`), browsers will block HTTP requests to the rig daemon (`http://localhost:5555`) due to **Mixed Content** security policies.
+
+**Browser Behavior:**
+
+| Browser | Behavior | Workaround |
+|---------|----------|------------|
+| **Safari (macOS/iOS)** | ❌ **Strictly blocks** all mixed content. No override option. | No workaround available. Use Chrome/Firefox/Edge or run OpenHamClock locally via HTTP. |
+| **Chrome** | ⚠️ Blocks by default. Shows shield icon in address bar to allow insecure content. | Click shield icon → "Load unsafe scripts" |
+| **Firefox** | ⚠️ Blocks by default. Shows shield icon in address bar. | Click shield icon → "Disable protection for this session" |
+| **Edge** | ⚠️ Blocks by default. Similar to Chrome. | Click shield icon → Allow |
+
+**Recommendation:** For the best experience, run OpenHamClock locally using HTTP (e.g., `http://localhost:3000`) to avoid mixed content issues entirely. See the [User Guide](./UserGuide.md) for detailed setup instructions.
+
+
+
## Experimental Scripts
The `scripts/` folder contains experimental installation and utility scripts. These are currently **in testing** and may not function properly on all systems. Use them with caution.
diff --git a/rig-control/UserGuide.md b/rig-control/UserGuide.md
index 6ab9dc93..c95cf435 100644
--- a/rig-control/UserGuide.md
+++ b/rig-control/UserGuide.md
@@ -11,9 +11,33 @@ This feature allows you to:
---
+## 📋 Choose Your Setup Scenario
+
+There are **two ways** to use Rig Control with OpenHamClock:
+
+### Scenario 1: Local Installation (Full Setup)
+You install **both** OpenHamClock and the Rig Control daemon on your local computer. This is ideal for:
+- Running everything on one machine (laptop, desktop, Raspberry Pi)
+- Development and testing
+- Offline operation
+
+👉 **[Jump to Scenario 1 Instructions](#scenario-1-local-installation)**
+
+### Scenario 2: Remote UI with Local Daemon
+You use the OpenHamClock web interface from **openhamclock.com** (or another hosted instance) but run **only the Rig Control daemon** locally on the computer connected to your radio. This is ideal for:
+- Using the hosted version without maintaining your own installation
+- Accessing from multiple devices while keeping rig control local
+- Simpler setup with fewer components to manage
+
+👉 **[Jump to Scenario 2 Instructions](#scenario-2-remote-ui-with-local-daemon)**
+
+---
+
+# Scenario 1: Local Installation
+
## 🛠 Prerequisites
-You need three things installed on the computer connected to your radio (e.g., Raspberry Pi, Mac, or PC):
+You need the following installed on the computer connected to your radio (e.g., Raspberry Pi, Mac, or PC):
1. **Git:** To download the software.
- [Download Git](https://git-scm.com/downloads)
@@ -28,8 +52,6 @@ You need three things installed on the computer connected to your radio (e.g., R
## 📦 Step 1: Install OpenHamClock
-If you haven't installed OpenHamClock yet, follow these steps.
-
1. Open your terminal/command prompt.
2. Download the code:
```bash
@@ -47,27 +69,27 @@ If you haven't installed OpenHamClock yet, follow these steps.
---
-## 🚀 Step 2: Install the Rig Control Bridge
+## 🚀 Step 2: Install the Rig Control Daemon
-The "Rig Control Bridge" (daemon) is a separate small program that sits between OpenHamClock and your radio software.
+The "Rig Control Daemon" is a separate small program that sits between OpenHamClock and your radio software.
1. Navigate to the `rig-control` folder:
```bash
cd rig-control
```
_(If you are in the main folder, just type `cd rig-control`)_
-2. Install the bridge libraries:
+2. Install the daemon libraries:
```bash
npm install
```
---
-## ⚙️ Step 3: Configure the Bridge
+## ⚙️ Step 3: Configure the Daemon
-Tell the bridge which radio software you use.
+Tell the daemon which radio software you use.
-1. Find `rig-config.json` in the `rig-control` folder.
+1. Find `rig-config.json` in the `rig-control` folder. If it doesn't exist, it will be created automatically from `rig-config.json.example` when you first start the daemon.
2. Edit it with any text editor.
### If using FLRIG (Easiest)
@@ -76,12 +98,18 @@ Ensure FLRIG is running and **XML-RPC** is enabled in its settings (Config > Set
```json
{
- "rigType": "flrig",
- "flrig": {
- "host": "127.0.0.1",
- "port": 12345
+ "server": {
+ "host": "0.0.0.0",
+ "port": 5555,
+ "cors": "*"
},
- "serverPort": 5555
+ "radio": {
+ "type": "flrig",
+ "host": "127.0.0.1",
+ "port": 12345,
+ "pollInterval": 1000,
+ "pttEnabled": false
+ }
}
```
@@ -89,12 +117,18 @@ Ensure FLRIG is running and **XML-RPC** is enabled in its settings (Config > Set
```json
{
- "rigType": "rigctld",
- "rigctld": {
- "host": "127.0.0.1",
- "port": 4532
+ "server": {
+ "host": "0.0.0.0",
+ "port": 5555,
+ "cors": "*"
},
- "serverPort": 5555
+ "radio": {
+ "type": "rigctld",
+ "host": "127.0.0.1",
+ "port": 4532,
+ "pollInterval": 1000,
+ "pttEnabled": false
+ }
}
```
@@ -124,7 +158,7 @@ In the `openhamclock/rig-control` folder:
node rig-daemon.js
```
-- This starts the **Bridge**.
+- This starts the **Daemon**.
- Standard Port: **5555**
- _Note: You do NOT visit this port in your browser. It runs in the background._
@@ -136,9 +170,10 @@ node rig-daemon.js
2. Go to **Settings** (Gear Icon) > **Station Settings**.
3. Scroll to **Rig Control**.
4. Check **Enable Rig Control**.
-5. Set **Host URL** to: `http://localhost:5555`
- - _(This points the Dashboard on port 3000 to the Bridge on port 5555)_.
+5. Set **Daemon URL** to: `http://localhost:5555`
+ - _(This points the Dashboard on port 3000 to the Daemon on port 5555)_.
6. **Optional:** Check **"Tune Button Enabled"** if you want to trigger your ATU.
+7. Click **Save**.
---
@@ -158,4 +193,189 @@ Navigate to the dashboard. You should see the Rig Control panel (if enabled).
- **Radio won't tune:** Ensure FLRIG is running and connected to the radio.
- **Double check ports:**
- Browser URL: `http://localhost:3000`
- - Settings Rig URL: `http://localhost:5555`
+ - Settings Daemon URL: `http://localhost:5555`
+
+---
+
+# Scenario 2: Remote UI with Local Daemon
+
+In this scenario, you use the OpenHamClock web interface from **openhamclock.com** (or another HTTPS-hosted instance) while running only the Rig Control daemon locally on the computer connected to your radio.
+
+## 🛠 Prerequisites
+
+You need the following installed on the computer connected to your radio:
+
+1. **Git:** To download the daemon software.
+ - [Download Git](https://git-scm.com/downloads)
+2. **Node.js:** The engine that runs the daemon.
+ - **Check:** Open a terminal and type `node -v`. (You want version 18 or higher).
+ - **Install:** [Download Node.js LTS](https://nodejs.org/).
+3. **Radio Software:** One of the following must be running and connected to your radio:
+ - **FLRIG (Recommended):** [Download FLRIG](http://www.w1hkj.com/files/flrig/)
+ - **Hamlib (rigctld):** For advanced users.
+
+---
+
+## 📦 Step 1: Install the Rig Control Daemon Only
+
+1. Open your terminal/command prompt.
+2. Download the OpenHamClock repository (we only need the `rig-control` folder):
+ ```bash
+ git clone https://github.com/HAMDevs/openhamclock.git
+ cd openhamclock/rig-control
+ ```
+3. Install the daemon dependencies:
+ ```bash
+ npm install
+ ```
+
+---
+
+## ⚙️ Step 2: Configure the Daemon
+
+1. Find `rig-config.json` in the `rig-control` folder. If it doesn't exist, it will be created automatically from `rig-config.json.example` when you first start the daemon.
+2. Edit it with any text editor.
+
+### If using FLRIG (Easiest)
+
+Ensure FLRIG is running and **XML-RPC** is enabled in its settings (Config > Setup > UI > XML-RPC).
+
+```json
+{
+ "server": {
+ "host": "0.0.0.0",
+ "port": 5555,
+ "cors": "*"
+ },
+ "radio": {
+ "type": "flrig",
+ "host": "127.0.0.1",
+ "port": 12345,
+ "pollInterval": 1000,
+ "pttEnabled": false
+ }
+}
+```
+
+### If using Hamlib (rigctld)
+
+```json
+{
+ "server": {
+ "host": "0.0.0.0",
+ "port": 5555,
+ "cors": "*"
+ },
+ "radio": {
+ "type": "rigctld",
+ "host": "127.0.0.1",
+ "port": 4532,
+ "pollInterval": 1000,
+ "pttEnabled": false
+ }
+}
+```
+
+---
+
+## ▶️ Step 3: Start the Daemon
+
+In the `openhamclock/rig-control` folder:
+
+```bash
+node rig-daemon.js
+```
+
+- This starts the **Daemon**.
+- Standard Port: **5555**
+- The daemon will run in the background and communicate with your radio software.
+
+---
+
+## 🔗 Step 4: Configure OpenHamClock Web UI
+
+### Important: HTTPS → HTTP Mixed Content Issue
+
+When you access OpenHamClock via **HTTPS** (e.g., `https://openhamclock.com`), your browser will **block** direct HTTP connections to your local daemon (`http://localhost:5555`) for security reasons. This is called a "Mixed Content" security policy.
+
+**Different browsers handle this differently:**
+
+| Browser | Behavior | Workaround Available? |
+|---------|----------|----------------------|
+| **Safari (macOS/iOS)** | ❌ Strictly blocks all mixed content | ❌ No workaround available |
+| **Chrome** | ⚠️ Blocks by default | ✅ Click shield icon in address bar → "Load unsafe scripts" |
+| **Firefox** | ⚠️ Blocks by default | ✅ Click shield icon in address bar → "Disable protection for this session" |
+| **Edge** | ⚠️ Blocks by default | ✅ Click shield icon in address bar → Allow |
+
+### ⚠️ Current Limitations
+
+**Safari Users:** Unfortunately, Safari does not provide any way to override mixed content blocking. If you're using Safari, you have two options:
+1. **Use a different browser** (Chrome, Firefox, or Edge) that allows mixed content overrides
+2. **Run OpenHamClock locally** using Scenario 1 (both UI and daemon on HTTP)
+
+**Chrome/Firefox/Edge Users:** You can use the browser's mixed content override feature (shield icon in address bar), but you'll need to re-enable it each time you reload the page.
+
+### 📝 Configuration Steps
+
+1. Open **https://openhamclock.com** (or your hosted instance) in your browser.
+2. Go to **Settings** (Gear Icon) > **Station Settings**.
+3. Scroll to **Rig Control**.
+4. Check **Enable Rig Control**.
+5. Set **Daemon URL** to: `http://localhost:5555`
+6. **Optional:** Check **"Tune Button Enabled"** if you want to trigger your ATU.
+7. Click **Save**.
+8. **If using Chrome/Firefox/Edge:** Look for the shield icon in your browser's address bar and click it to allow mixed content.
+
+> **💡 Recommendation:** For the best experience with rig control, consider using **Scenario 1** (local installation) where both the UI and daemon run on HTTP, avoiding mixed content issues entirely.
+
+---
+
+## ✅ You're Done!
+
+Navigate to the dashboard at **https://openhamclock.com**. You should see the Rig Control panel (if enabled).
+
+**Try it out:**
+- Click a spot on the **World Map**.
+- Click a row in the **DX Cluster** list.
+- Click a **POTA** or **SOTA** spot.
+- Works across **Classic**, **Modern**, **Tablet**, and **Compact** layouts!
+
+### Troubleshooting
+
+- **"Connection Failed":**
+ - Ensure `node rig-daemon.js` is running in a terminal.
+ - Verify the daemon is listening on port 5555 (check terminal output).
+ - **If using HTTPS UI:** Check for mixed content blocking (see browser-specific workarounds above).
+
+- **Radio won't tune:**
+ - Ensure FLRIG or rigctld is running and connected to the radio.
+ - Check the daemon terminal output for error messages.
+
+- **Mixed Content Errors (Console):**
+ - **Safari:** No workaround available. Use Chrome/Firefox/Edge or switch to Scenario 1.
+ - **Chrome/Firefox/Edge:** Click the shield icon in the address bar to allow mixed content.
+ - **Best Solution:** Consider using Scenario 1 (local installation) to avoid this issue entirely.
+
+- **Firewall Issues:**
+ - If the daemon is on a different machine than your browser, ensure port 5555 is open in your firewall.
+ - Update the **Daemon URL** to use the daemon machine's IP address (e.g., `http://192.168.1.50:5555`).
+
+---
+
+## 🎯 Quick Reference
+
+### Scenario 1 (Local Installation)
+- **What you install:** OpenHamClock + Rig Control Daemon
+- **What you run:** `npm start` (OpenHamClock) + `node rig-daemon.js` (Daemon)
+- **Where you access UI:** `http://localhost:3000`
+- **Daemon URL in Settings:** `http://localhost:5555`
+- **Browser compatibility:** All browsers ✅
+- **Mixed content issues:** None (both on HTTP)
+
+### Scenario 2 (Remote UI)
+- **What you install:** Rig Control Daemon only
+- **What you run:** `node rig-daemon.js` (Daemon)
+- **Where you access UI:** `https://openhamclock.com` (or your hosted instance)
+- **Daemon URL in Settings:** `http://localhost:5555` (or `http://your-daemon-ip:5555`)
+- **Browser compatibility:** Chrome/Firefox/Edge ✅ (with manual override) | Safari ❌
+- **Mixed content issues:** Requires browser override on each page load (Chrome/Firefox/Edge only)
diff --git a/rig-control/rig-config.json.example b/rig-control/rig-config.json.example
new file mode 100644
index 00000000..73d6506b
--- /dev/null
+++ b/rig-control/rig-config.json.example
@@ -0,0 +1,24 @@
+{
+ "server": {
+ "host": "0.0.0.0",
+ "port": 5555,
+ "cors": "*"
+ },
+ "radio": {
+ "type": "flrig",
+ "host": "127.0.0.1",
+ "port": 12345,
+ "pollInterval": 1000,
+ "timeout": 5000,
+ "tuneDelay": 3000,
+ "pttEnabled": false,
+ "_comment": "Set type to 'rigctld' (TCP), 'flrig' (XML-RPC), or 'mock' (Simulation)"
+ },
+ "rotator": {
+ "enabled": false,
+ "type": "rotctld",
+ "host": "127.0.0.1",
+ "port": 4533,
+ "pollInterval": 1000
+ }
+}
diff --git a/rig-control/rig-daemon.js b/rig-control/rig-daemon.js
index 78498707..f2f7f1a8 100644
--- a/rig-control/rig-daemon.js
+++ b/rig-control/rig-daemon.js
@@ -32,6 +32,18 @@ let CONFIG = {
// Load Config File
const configPath = path.join(__dirname, "rig-config.json");
+const exampleConfigPath = path.join(__dirname, "rig-config.json.example");
+
+// Auto-create config from example if it doesn't exist
+if (!fs.existsSync(configPath) && fs.existsSync(exampleConfigPath)) {
+ try {
+ fs.copyFileSync(exampleConfigPath, configPath);
+ console.log(`[Config] Created ${configPath} from example template`);
+ } catch (e) {
+ console.warn(`[Config] Could not create config from example: ${e.message}`);
+ }
+}
+
if (fs.existsSync(configPath)) {
try {
const fileConfig = JSON.parse(fs.readFileSync(configPath, "utf8"));
diff --git a/scripts/update.sh b/scripts/update.sh
index 937ed3ae..9d9bd18c 100644
--- a/scripts/update.sh
+++ b/scripts/update.sh
@@ -140,6 +140,12 @@ if [ -f "config.json" ]; then
echo " ✓ config.json → config.json.backup"
fi
+# Backup rig control daemon config
+if [ -f "rig-control/rig-config.json" ]; then
+ cp rig-control/rig-config.json rig-control/rig-config.json.backup
+ echo " ✓ rig-control/rig-config.json → rig-config.json.backup"
+fi
+
echo ""
echo "⬇️ Pulling latest changes..."
@@ -208,6 +214,16 @@ if [ -f "config.json.backup" ] && [ ! -f "config.json" ]; then
echo " ✓ config.json restored from backup"
fi
+# Restore rig control daemon config
+if [ -f "rig-control/rig-config.json.backup" ]; then
+ cp rig-control/rig-config.json.backup rig-control/rig-config.json
+ echo " ✓ rig-control/rig-config.json restored from backup"
+elif [ ! -f "rig-control/rig-config.json" ] && [ -f "rig-control/rig-config.json.example" ]; then
+ # First-time setup: copy example to actual config
+ cp rig-control/rig-config.json.example rig-control/rig-config.json
+ echo " ✓ rig-control/rig-config.json created from example template"
+fi
+
# Patch kiosk.sh if present — fix --incognito flag that wipes localStorage on reboot
if [ -f "kiosk.sh" ]; then
if grep -q "\-\-incognito" kiosk.sh; then
diff --git a/src/DockableApp.jsx b/src/DockableApp.jsx
index 81395773..9d26d207 100644
--- a/src/DockableApp.jsx
+++ b/src/DockableApp.jsx
@@ -186,11 +186,19 @@ export const DockableApp = ({
if (!spot) return;
// 1. Tune Rig if frequency is available and rig control is enabled
- // Spot freq is usually in kHz or MHz string
- if (enabled && (spot.freq || spot.freqMHz)) {
- const freq = spot.freq || (parseFloat(spot.freqMHz) * 1000); // Normalize to kHz for tuneTo (which handles units)
- // tuneTo handles unit detection (MHz vs kHz vs Hz) so just pass the raw value
- tuneTo(spot.freq || spot.freqMHz, spot.mode);
+ if (enabled && (spot.freq || spot.freqMHz || spot.dialFrequency)) {
+ let freqToSend;
+
+ // WSJT-X decodes have dialFrequency (the VFO frequency to tune to)
+ // The freq field is just the audio delta offset within the passband
+ if (spot.dialFrequency) {
+ freqToSend = spot.dialFrequency; // Use dial frequency directly
+ } else {
+ // For other spot types (DX Cluster, POTA, etc.), use freq or freqMHz as-is
+ freqToSend = spot.freq || spot.freqMHz;
+ }
+
+ tuneTo(freqToSend, spot.mode);
}
// 2. Set DX Location if location data is available
@@ -561,10 +569,11 @@ export const DockableApp = ({
showLabelsOnMap={mapLayersEff.showPOTALabels}
onToggleLabelsOnMap={togglePOTALabelsEff}
+ onSpotClick={handleSpotClick}
/>
);
break;
-
+
case 'wwff':
content = (