Transform your old Android tablet into a real-time system monitoring server with WebSocket connectivity
- Overview
- Features
- Architecture
- Technologies
- System Requirements
- Installation
- Usage
- API Documentation
- Project Structure
- Monitoring Metrics
- WebSocket Protocol
- Troubleshooting
- Contributing
- License
This project transforms an old Android tablet (like Samsung Galaxy Tab 2 GT-P3110) into a real-time system monitoring server. The tablet collects telemetry data (CPU usage, RAM, battery level, temperature) and streams it via WebSocket to a Spring Boot server, which then broadcasts the data to web clients in real-time.
Perfect for:
- 🔄 Repurposing old Android devices
- 📊 Real-time system monitoring dashboards
- 🎓 Learning WebSocket communication
- 🏗️ IoT and telemetry projects
- ✅ Headless Service - Runs in background without UI to save RAM
- ✅ Real-time Metrics Collection - CPU, RAM, Battery, Temperature
- ✅ WebSocket Server - Built-in NanoWSD server on port 8081
- ✅ Root Access Support - Enhanced temperature monitoring with root
- ✅ Auto-reconnection - Resilient connection handling
- ✅ Remote Commands - Stress testing capabilities (CPU stress, RAM fill/clear)
- ✅ WebSocket Bridge - Connects tablet to web clients
- ✅ Auto-reconnection - Automatic reconnection to tablet on disconnect
- ✅ Multi-client Support - Broadcast metrics to multiple web clients
- ✅ Real-time Streaming - 5-second update intervals
- ✅ REST API Ready - Easy integration with frontend applications
┌─────────────────┐ WebSocket ┌──────────────────┐ WebSocket ┌─────────────────┐
│ Old Android │ (Port 8081) │ Spring Boot │ (Port 8080) │ Web Clients │
│ Tablet │ ────────────────────────> │ Server │ ─────────────────────> │ (Frontend) │
│ (T110_Server) │ Telemetry Data JSON │ (Bridge/Relay) │ Broadcast Metrics │ Dashboard │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
│ Collects: │ Displays:
│ - CPU Usage │ - Real-time Charts
│ - RAM Available │ - System Status
│ - Battery % │ - Alerts
│ - Temperature │ - Historical Data
└─────────────────────────────────────────────────────────────────────────────────────────────┘
- Tablet Monitoring Service collects system metrics every 5 seconds
- NanoWSD WebSocket Server (on tablet) sends JSON telemetry to Spring Boot server
- Spring Boot WebSocket Client receives data from tablet
- Spring Boot WebSocket Server broadcasts data to all connected web clients
- Web Frontend displays real-time metrics and allows remote commands
| Technology | Version | Purpose |
|---|---|---|
| Spring Boot | 3.5.7 | Main application framework |
| Spring WebSocket | 3.5.7 | WebSocket support for bi-directional communication |
| Spring Web | 3.5.7 | REST API endpoints |
| Lombok | Latest | Reduce boilerplate code |
| Java | 17 | Programming language |
| Maven | 3.x | Dependency management |
| Technology | Version | Purpose |
|---|---|---|
| Android SDK | API 21+ | Android platform |
| NanoHTTPD/NanoWSD | Latest | Lightweight WebSocket server |
| Java | 8+ | Programming language |
| Gradle | 8.x | Build tool |
✓ Java 17 or higher
✓ Maven 3.6+ or Gradle 7+
✓ 512 MB RAM minimum
✓ Network connectivity to tablet
✓ Android 5.0 (API 21) or higher
✓ WiFi connectivity
✓ Root access (optional, for enhanced temperature monitoring)
✓ 256 MB RAM minimum
✓ Static IP address recommended
git clone https://github.com/vitinh0z/ServerWIthOldTabletAndTelemetricWithSpringBoot.git
cd ServerWIthOldTabletAndTelemetricWithSpringBootcd TabletServer
# Build with Maven
./mvnw clean install
# Or use Maven Wrapper on Windows
mvnw.cmd clean installEdit TabletServer/src/main/java/io/github/vitinh0z/TabletServer/TabletClientConnector.java:
private static final String TABLET_SERVER_URI = "ws://192.168.15.4:8081";
// ^^^^^^^^^^^^^^
// Update with your tablet's IPcd MonitorServiceClient
# Build APK
./gradlew assembleDebug
# Or on Windows
gradlew.bat assembleDebugInstall the APK on your tablet:
adb install app/build/outputs/apk/debug/app-debug.apk- Install and launch the app on your tablet
- The service starts automatically and runs in the background
- Note the tablet's IP address (Settings → WiFi → Your Network)
- Verify WebSocket server is running on port 8081
cd TabletServer
# Run with Maven
./mvnw spring-boot:run
# Or run the JAR
java -jar target/TabletServer-0.0.1-SNAPSHOT.jarServer will start on http://localhost:8080
Connect to the WebSocket endpoint:
ws://localhost:8080/tablet-metrics
Check the logs:
Spring Boot Console:
CONECTADO AO SERVIDOR DO TABLET!
Métrica recebida do Tablet: {"deviceId":"T110_Servidor","cpuUsage":12,"ramAvailableMb":234,...}
Android Logcat:
adb logcat | grep TabletServiceExpected output:
TabletService: Cliente Conectado (SpringBoot)
TabletService: Enviando JSON {"deviceId":"T110_Servidor",...}
Endpoint: ws://localhost:8080/tablet-metrics
Description: Web clients connect here to receive real-time metrics
Message Format (Received):
{
"deviceId": "T110_Servidor",
"cpuUsage": 15,
"ramAvailableMb": 234,
"batteryPct": 87,
"temperatureC": 35.2,
"timestamp": 1700234567890
}Remote Commands (Sent):
"CMD_STRESS_CPU" // Stress test CPU for 10 seconds
"CMD_FILL_RAM" // Allocate 50 MB of RAM
"CMD_CLEAR_RAM" // Release allocated RAMEndpoint: ws://[TABLET_IP]:8081
Description: Spring Boot server connects to tablet's WebSocket server
Auto-reconnection: Yes (10-second interval on disconnect)
ServerWIthOldTabletAndTelemetricWithSpringBoot/
│
├── TabletServer/ # Spring Boot Server Application
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/.../TabletServer/
│ │ │ │ ├── TabletServerApplication.java # Main Spring Boot application
│ │ │ │ ├── TabletClientConnector.java # WebSocket client to tablet
│ │ │ │ ├── config/
│ │ │ │ │ └── WebSocketConfig.java # WebSocket configuration
│ │ │ │ ├── model/
│ │ │ │ │ └── TabletMetricsModel.java # Metrics data model
│ │ │ │ └── websocket/
│ │ │ │ └── TabletHandlerWebSocket.java # WebSocket handler for clients
│ │ │ └── resources/
│ │ │ └── application.properties # Server configuration
│ │ └── test/
│ ├── pom.xml # Maven dependencies
│ └── mvnw # Maven wrapper
│
└── MonitorServiceClient/ # Android Tablet Application
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/io/github/vitinh0z/
│ │ │ │ ├── MainActivity.java # Launcher activity
│ │ │ │ └── MonitorService.java # Background monitoring service
│ │ │ ├── AndroidManifest.xml # App manifest
│ │ │ └── res/ # Android resources
│ │ └── build.gradle.kts # Gradle build configuration
│ └── proguard-rules.pro
├── build.gradle.kts
└── settings.gradle.kts
| Metric | Type | Description | Update Interval |
|---|---|---|---|
| CPU Usage | Integer (%) | Current CPU usage percentage (0-100) | 5 seconds |
| RAM Available | Integer (MB) | Available memory in megabytes | 5 seconds |
| Battery Level | Integer (%) | Battery charge percentage (0-100) | 5 seconds |
| Temperature | Float (°C) | Device temperature in Celsius | 5 seconds |
| Device ID | String | Unique device identifier | Static |
| Timestamp | Long | Unix timestamp in milliseconds | Per message |
{
"deviceId": "T110_Servidor",
"cpuUsage": 15,
"ramAvailableMb": 234,
"batteryPct": 87,
"temperatureC": 35.2,
"timestamp": 1700234567890
}- Range: 0-100%
- Calculation: Simulated (actual CPU monitoring requires more complex implementation)
- Stress Mode: When stressed, reports 80-95% usage
- Normal Mode: Reports 5-15% usage
- Unit: Megabytes (MB)
- Source:
ActivityManager.getMemoryInfo() - Note: Shows available RAM, not total or used
- Range: 0-100%
- Source: Android BatteryManager
- Accuracy: ±1%
- Unit: Celsius (°C)
- Source:
/sys/class/power_supply/battery/temp(requires root) - Precision: 0.1°C
- Fallback: Returns 0 if unable to read
┌─────────┐ ┌──────────┐ ┌────────┐
│ Tablet │ │ Spring │ │ Client │
└────┬────┘ └────┬─────┘ └───┬────┘
│ │ │
│ 1. Start NanoWSD │ │
│ (Port 8081) │ │
│ │ │
│ 2. Connect │ │
│<─────────────────────────│ │
│ │ │
│ 3. Send "onOpen" │ │
│─────────────────────────>│ │
│ │ │
│ 4. Start metrics │ 5. Client connects │
│ (5s interval) │<─────────────────────────│
│ │ │
│ 6. JSON metrics │ │
│─────────────────────────>│ 7. Broadcast metrics │
│ │─────────────────────────>│
│ │ │
│ 8. Receive command │ 9. Send command │
│<─────────────────────────│<─────────────────────────│
│ │ │
│ 10. Execute & respond │ │
│─────────────────────────>│─────────────────────────>│
│ │ │
- Connection Lost: 10-second retry interval
- Invalid JSON: Logged and ignored
- Command Errors: Logged without crashing service
- Root Access Failure: Falls back to non-root methods
Symptoms:
Falha ao conectar ao Tablet: Connection refused. Tentando reconectar em 10s...
Solutions:
- ✅ Verify tablet IP address is correct in
TabletClientConnector.java - ✅ Ensure tablet and server are on the same network
- ✅ Check firewall settings on both devices
- ✅ Verify NanoWSD server is running on tablet (check logcat)
- ✅ Try pinging the tablet:
ping 192.168.15.4
Solutions:
- ✅ Check logcat for errors:
adb logcat | grep TabletService - ✅ Verify app has necessary permissions (INTERNET, ACCESS_NETWORK_STATE)
- ✅ Reinstall the APK
- ✅ Clear app data and restart
Solutions:
- ✅ Grant root access to the app
- ✅ Check if temperature file exists:
adb shell su -c "cat /sys/class/power_supply/battery/temp" - ✅ Some devices use different paths - may need code modification
Solutions:
- ✅ Increase update interval in
MonitorService.java(change UPDATE_INTERVALO) - ✅ Disable stress testing features
- ✅ Close other apps on tablet
- ✅ Consider using a more powerful device
# View Android logs
adb logcat | grep TabletService
# Check if service is running
adb shell dumpsys activity services | grep MonitorService
# Test WebSocket connectivity
wscat -c ws://192.168.15.4:8081
# View Spring Boot logs
tail -f TabletServer/logs/spring-boot.log<!DOCTYPE html>
<html>
<head>
<title>Tablet Monitor Dashboard</title>
<style>
.metric { padding: 10px; margin: 10px; border: 1px solid #ccc; }
.high { background-color: #ffcccc; }
.normal { background-color: #ccffcc; }
</style>
</head>
<body>
<h1>📱 Tablet System Monitor</h1>
<div id="metrics"></div>
<button onclick="sendCommand('CMD_STRESS_CPU')">🔥 Stress CPU</button>
<button onclick="sendCommand('CMD_FILL_RAM')">📊 Fill RAM</button>
<button onclick="sendCommand('CMD_CLEAR_RAM')">🧹 Clear RAM</button>
<script>
const ws = new WebSocket('ws://localhost:8080/tablet-metrics');
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
document.getElementById('metrics').innerHTML = `
<div class="metric ${data.cpuUsage > 70 ? 'high' : 'normal'}">
CPU: ${data.cpuUsage}%
</div>
<div class="metric">RAM: ${data.ramAvailableMb} MB</div>
<div class="metric">Battery: ${data.batteryPct}%</div>
<div class="metric ${data.temperatureC > 40 ? 'high' : 'normal'}">
Temp: ${data.temperatureC}°C
</div>
<div class="metric">Updated: ${new Date(data.timestamp).toLocaleString()}</div>
`;
};
function sendCommand(cmd) {
ws.send(cmd);
}
</script>
</body>
</html>import React, { useEffect, useState } from 'react';
function TabletMonitor() {
const [metrics, setMetrics] = useState(null);
const [ws, setWs] = useState(null);
useEffect(() => {
const websocket = new WebSocket('ws://localhost:8080/tablet-metrics');
websocket.onmessage = (event) => {
const data = JSON.parse(event.data);
setMetrics(data);
};
setWs(websocket);
return () => websocket.close();
}, []);
const sendCommand = (cmd) => {
if (ws) ws.send(cmd);
};
if (!metrics) return <div>Connecting...</div>;
return (
<div className="tablet-monitor">
<h2>📱 {metrics.deviceId}</h2>
<div className="metrics-grid">
<MetricCard title="CPU" value={`${metrics.cpuUsage}%`} />
<MetricCard title="RAM" value={`${metrics.ramAvailableMb} MB`} />
<MetricCard title="Battery" value={`${metrics.batteryPct}%`} />
<MetricCard title="Temperature" value={`${metrics.temperatureC}°C`} />
</div>
<div className="controls">
<button onClick={() => sendCommand('CMD_STRESS_CPU')}>Stress CPU</button>
<button onClick={() => sendCommand('CMD_FILL_RAM')}>Fill RAM</button>
<button onClick={() => sendCommand('CMD_CLEAR_RAM')}>Clear RAM</button>
</div>
</div>
);
}Monitor old devices in your home lab setup, tracking system health and performance.
Perfect for learning WebSocket communication, real-time data streaming, and Android services.
Give new life to old Android tablets that would otherwise be discarded.
Use remote commands to stress test devices and monitor their behavior under load.
Demonstrate real-time communication, system monitoring, and multi-tier architecture.
Contributions are welcome! Here's how you can help:
- 🐛 Report Bugs - Open an issue with detailed reproduction steps
- 💡 Suggest Features - Share your ideas for improvements
- 📝 Improve Documentation - Fix typos, add examples, clarify instructions
- 🔧 Submit Pull Requests - Fix bugs or implement new features
# Fork the repository
git clone https://github.com/YOUR_USERNAME/ServerWIthOldTabletAndTelemetricWithSpringBoot.git
# Create a feature branch
git checkout -b feature/my-new-feature
# Make your changes and commit
git commit -am 'Add some feature'
# Push to your fork
git push origin feature/my-new-feature
# Create a Pull Request- ✅ Follow existing code style and formatting
- ✅ Add comments for complex logic
- ✅ Write meaningful commit messages
- ✅ Test your changes thoroughly
- ✅ Update documentation as needed
This project is licensed under the MIT License - see the LICENSE file for details.
vitinh0z
- GitHub: @vitinh0z
- NanoHTTPD/NanoWSD - Lightweight Java web server
- Spring Boot Team - Excellent framework and documentation
- Android Open Source Project - Android platform and APIs
If you need help or have questions:
- 📖 Check the Troubleshooting section
- 🐛 Open an Issue
- 💬 Start a Discussion
⭐ Star this repository if you find it useful!
Made with ❤️ for repurposing old Android devices