A standalone Node.js / Express web application for controlling a ham radio station from any browser on your local network. It replaces a Node-RED dashboard and talks to the same equipment directly — Node-RED does not need to be running.
Designed to run on Windows 11 on the same PC as your station software.
| Device | Interface | What you can do |
|---|---|---|
| FlexRadio 8600 | UDP discovery (4992) + TCP | View slices A & B (freq/mode/active), Temp, fan RPM, RX & TX filter passband, APD on/off/calibrating/calibrated; 10 real-time meters (FWD power, SWR, PA volts/temp, fan RPM…), set RF power, link watchdog |
| Palstar LA-1K Amp | Serial (COM7, 9600 8N1) | Operate/Standby, antenna 1/2/3 select, FWD power, temperature, band & key status |
| Yaesu G-800DXA (EA4TX ERC-Mini) | Serial (COM5, 9600 baud, GS-232B) | Live compass display, heading presets, manual azimuth, CCW/CW jog, stop |
| Palstar HF-Auto Tuner | Serial (COM4, 4800 8N2, binary frames) | Antenna select, tuner mode (Bypass/Auto — Manual is front-panel only), SWR / TX watts / peak power, C/L readout, set-frequency feed, offline watchdog |
| Home Assistant | REST API + MQTT (192.168.1.54) | Power buttons switch HA entities via switch.turn_on/off (REST + long-lived token); MQTT mirrors station state |
- 🔐 Authentication with JWT tokens and three roles
- Admin — full control plus user management & configuration
- Normal — full device control, can change own password
- View-Only — sees everything, cannot operate anything
- 👤 Pre-configured admin
wb0z(change the password on first login!) - 🔑 Every user can change their own password; admins can add users, set roles, reset passwords
- 📊 Live dashboard with status panels for every device
- 🎛️ Role-aware controls (buttons/sliders disabled for view-only users)
- 🎨 Theme / color-palette customizer with live preview (4 themes included, create your own)
- ⚙️ Admin Settings screen — edit MQTT (broker/port/user/pass), serial COM ports & baud rates, FlexRadio discovery/TCP ports, Home Assistant entity IDs, and general server settings; saved straight to
config.json - ⚡ Real-time updates over WebSocket — no page refresh needed
- 📱 Responsive layout for desktop and tablets
- 💾 Simple JSON file storage — no database to install
- 🧩 Carried-over automation rules from Node-RED (amp RF-power limiting, tuner antenna→mode rules, watchdogs)
cd C:\ham_radio_web_app
npm install
npm startThen open http://localhost:3000 and sign in:
| Username | Password |
|---|---|
wb0z |
Jasonar-8806 |
⚠️ Change the admin password immediately from the Change Password button.
Full setup instructions: docs/INSTALLATION.md Every config setting explained: docs/CONFIGURATION.md
ham_radio_web_app/
├── package.json
├── server/ # Express backend
│ ├── index.js # entry point: HTTP + WS + services
│ ├── setup.js # first-run bootstrap (admin user, JWT secret)
│ ├── storage.js # JSON file persistence
│ ├── auth.js # JWT + role middleware
│ ├── websocket.js # real-time push to browsers
│ ├── middleware/
│ │ └── lan-only.js # IP gate for /api/admin
│ ├── routes/ # REST API
│ │ ├── auth.js # login, me, change-password
│ │ ├── users.js # user CRUD (admin)
│ │ ├── devices.js # status + control endpoints
│ │ ├── config.js # read/update configuration
│ │ ├── settings.js # admin settings screen (flattened config)
│ │ ├── admin.js # LAN-only diagnostics: health, logs, restart
│ │ └── themes.js # theme storage
│ └── services/ # device integration framework
│ ├── state.js # central live state + event bus
│ ├── logbuffer.js # in-memory log ring for /api/admin/logs
│ ├── serial.js # Palstar LA-1K amp (serialport)
│ ├── rotator.js # Antenna rotator ERC-Mini GS-232B (serial)
│ ├── tuner.js # HF-Auto Tuner (serial, binary frames)
│ ├── mqtt.js # Home Assistant MQTT status bridge
│ ├── homeassistant.js# HA REST control (switch.turn_on/off via token)
│ └── flexradio.js # FlexRadio 8600 discovery/TCP
├── client/ # Frontend (vanilla JS, no build step)
│ ├── index.html # login
│ ├── dashboard.html # main UI
│ ├── settings.html # admin settings screen
│ ├── css/styles.css # theme-driven styling
│ └── js/ # api, login, dashboard, settings, theme, users, azmap
├── mcp/ # MCP server exposing status/logs/restart to Claude
├── config/ # JSON configuration & data
│ ├── config.template.json
│ ├── config.json # generated on first run
│ ├── themes.json
│ └── users.json # generated on first run
└── docs/ # README / INSTALLATION / CONFIGURATION
- The browser authenticates and receives a JWT.
- A WebSocket (
/ws?token=…) streams device state to the dashboard in real time. - Control actions are REST calls (
POST /api/devices/...). View-only users are blocked at the server (HTTP 403) and in the UI. - Backend services translate those calls into serial / TCP / MQTT / HA REST messages and push resulting state changes back through the WebSocket.
| Method & path | Role | Purpose |
|---|---|---|
POST /api/auth/login |
any | Get a token |
GET /api/auth/me |
any auth | Current user |
POST /api/auth/change-password |
any auth | Change own password |
GET /api/devices/status |
any auth | Full live state snapshot |
POST /api/devices/flex/rfpower |
admin/normal | Set FlexRadio RF power |
POST /api/devices/flex/apd |
admin/normal | Toggle APD |
POST /api/devices/amp/mode |
admin/normal | Operate / Standby |
POST /api/devices/amp/antenna |
admin/normal | Amp antenna 1–3 |
POST /api/devices/rotator/azimuth |
admin/normal | Turn rotator |
POST /api/devices/rotator/jog |
admin/normal | Jog CW/CCW (heartbeat, 2 s watchdog) |
POST /api/devices/rotator/stop |
admin/normal | Stop rotator |
POST /api/devices/tuner/mode |
admin/normal | Tuner mode |
POST /api/devices/tuner/antenna |
admin/normal | Tuner antenna 1–3 |
POST /api/devices/power/:device |
admin/normal | Toggle supply/radio/amp |
GET/PUT /api/config |
admin | Read / save config |
GET /api/config/public |
any auth | UI-safe config subset |
GET /api/themes, POST /api/themes, PUT /api/themes/active, DELETE /api/themes/:id |
varies | Theme management |
GET/POST/PUT/DELETE /api/users |
admin | User management |
GET /api/settings |
admin | Read flattened, editable settings |
PUT /api/settings |
admin | Validate & save settings to config.json |
GET /api/admin/health, GET /api/admin/logs, GET /api/admin/status |
LAN only | Diagnostics (no auth, IP-gated) |
POST /api/admin/restart |
LAN + admin | Graceful restart (process manager relaunches) |
- The device services are a working framework built from your Node-RED export.
The amp, rotator and tuner all speak their native serial protocols directly and
will operate the hardware. The FlexRadio module implements discovery, the TCP channel, the
subscription handshake and a status/meter parser covering the dashboard values;
the SmartSDR command set can be extended in
server/services/flexradio.js. - If a library or device is missing, that service degrades gracefully (e.g. the amp enters simulation mode) and the rest of the app keeps running.
- This server is intended for a trusted home LAN. For internet exposure, place it behind a reverse proxy with HTTPS.
MIT — free to use and modify for your own station.