# SPORE UI

Zero-configuration web interface for monitoring and managing SPORE embedded systems.

## Features

- **🌐 Cluster Monitoring**: Real-time view of all cluster members with auto-discovery
- **📊 Node Details**: Detailed system information including running tasks and available endpoints
- **🚀 OTA**: Clusterwide over-the-air firmware updates
- **📱 Responsive**: Works on all devices and screen sizes
- **🖥️ Terminal**: Terminal for interacting with a node's WebSocket

## Screenshots
### Cluster
![UI](./assets/cluster.png)  
### Topology
![UI](./assets/topology.png)  
### Monitoring
![UI](./assets/monitoring.png)  
### Firmware
![UI](./assets/firmware.png)

## Getting Started

1. **Install dependencies**: `npm install`
2. **Start the server**: `npm start`
3. **Open in browser**: `http://localhost:3001`

## API Endpoints

- **`/`** - Main UI page
- **`/api/cluster/members`** - Get cluster member information
- **`/api/tasks/status`** - Get task status
- **`/api/node/status`** - Get system status
- **`/api/node/status/:ip`** - Get status from specific node

## Technologies Used

- **Backend**: Express.js, Node.js
- **Frontend**: Vanilla JavaScript, CSS3, HTML5
- **Framework**: Custom component-based architecture
- **API**: SPORE Embedded System API
- **Design**: Glassmorphism, CSS Grid, Flexbox

## UDP Heartbeat Discovery

The backend now includes automatic UDP heartbeat-based discovery for SPORE nodes on the network. This eliminates the need for hardcoded IP addresses and provides a self-healing, scalable solution for managing SPORE clusters.

### 🚀 How It Works

1. **UDP Server**: The backend listens on port 4210 for UDP messages
2. **Heartbeat Message**: Nodes send `CLUSTER_HEARTBEAT` messages to broadcast address `255.255.255.255:4210`
3. **Auto Configuration**: When a heartbeat message is received, the source IP is automatically used to configure the SporeApiClient
4. **Dynamic Updates**: The system automatically switches to the most recently seen node as the primary connection
5. **Health Monitoring**: Continuous monitoring of node availability with automatic failover

### 📡 Heartbeat Protocol

- **Port**: 4210 (configurable via `UDP_PORT` constant)
- **Message**: `CLUSTER_HEARTBEAT` (configurable via `HEARTBEAT_MESSAGE` constant)
- **Broadcast**: `255.255.255.255:4210`
- **Protocol**: UDP broadcast listening
- **Auto-binding**: Automatically binds to the specified port on startup

### 🔧 Setup Instructions

#### Backend Setup
```bash
# Start the backend server
npm start

# The server will automatically:
# - Start HTTP server on port 3001
# - Start UDP heartbeat server on port 4210
# - Wait for CLUSTER_HEARTBEAT messages
```

#### Node Configuration
SPORE nodes should send heartbeat messages periodically:
```bash
# Recommended: Send every 30-60 seconds
# Message format: "CLUSTER_HEARTBEAT:hostname"
# Target: 255.255.255.255:4210
```

### 🌐 Cluster Endpoints

#### Cluster Management
- `GET /api/discovery/nodes` - View all cluster nodes and current status
- `POST /api/discovery/refresh` - Manually trigger cluster refresh
- `POST /api/discovery/primary/:ip` - Manually set a specific node as primary
- `POST /api/discovery/random-primary` - Randomly select a new primary node

#### Health Monitoring
- `GET /api/health` - Comprehensive health check including cluster status

### 🧪 Testing & Development

#### Test Scripts
```bash
# Send discovery messages to test the system
npm run test-discovery broadcast

# Send to specific IP
npm run test-discovery 192.168.1.100

# Send multiple messages
npm run test-discovery broadcast 5

# Test random primary node selection
npm run test-random-selection

# Monitor discovery in real-time
npm run demo-discovery
```

#### Manual Testing
```bash
# Check discovery status
curl http://localhost:3001/api/discovery/nodes

# Check health
curl http://localhost:3001/api/health

# Manual refresh
curl -X POST http://localhost:3001/api/discovery/refresh

# Random primary selection
curl -X POST http://localhost:3001/api/discovery/random-primary

# Set specific primary
curl -X POST http://localhost:3001/api/discovery/primary/192.168.1.100
```

### 🔍 Troubleshooting

#### Common Issues

**No Nodes Discovered**
```bash
# Check if backend is running
curl http://localhost:3001/api/health

# Verify UDP port is open
netstat -tulpn | grep 4210

# Send test discovery message
npm run test-discovery broadcast
```

**UDP Port Already in Use**
```bash
# Check for conflicting processes
netstat -tulpn | grep 4210

# Kill conflicting processes or change port in code
# Restart backend server
```

**Client Not Initialized**
```bash
# Check discovery status
curl http://localhost:3001/api/discovery/nodes

# Verify nodes are sending discovery messages
# Check network connectivity
```

#### Debug Commands
```bash
# Check discovery status
curl http://localhost:3001/api/discovery/nodes

# Check health
curl http://localhost:3001/api/health

# Manual refresh
curl -X POST http://localhost:3001/api/discovery/refresh

# Set primary node
curl -X POST http://localhost:3001/api/discovery/primary/192.168.1.100
```
