Files
aitbc/apps/miner-dashboard/dashboard_server.py
oib 9b9c5beb23 ```
chore: enhance .gitignore and remove obsolete documentation files

- Reorganize .gitignore with categorized sections for better maintainability
- Add comprehensive ignore patterns for Python, Node.js, databases, logs, and build artifacts
- Add project-specific ignore rules for coordinator, explorer, and deployment files
- Remove outdated documentation: BITCOIN-WALLET-SETUP.md, LOCAL_ASSETS_SUMMARY.md, README-CONTAINER-DEPLOYMENT.md, README-DOMAIN-DEPLOYMENT.md
```
2026-01-24 14:44:51 +01:00

186 lines
7.2 KiB
Python

#!/usr/bin/env python3
"""AITBC Miner Dashboard API - Real-time GPU and mining status"""
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import subprocess
import psutil
from datetime import datetime, timedelta
import random
class MinerDashboardHandler(BaseHTTPRequestHandler):
def send_json_response(self, data, status=200):
"""Send JSON response"""
self.send_response(status)
self.send_header('Content-Type', 'application/json')
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
self.wfile.write(json.dumps(data, default=str).encode())
def do_GET(self):
"""Handle GET requests"""
if self.path == '/api/gpu-status':
self.get_gpu_status()
elif self.path == '/api/mining-jobs':
self.get_mining_jobs()
elif self.path == '/api/statistics':
self.get_statistics()
elif self.path == '/api/services':
self.get_services()
elif self.path == '/' or self.path == '/index.html':
self.serve_dashboard()
else:
self.send_error(404)
def get_gpu_status(self):
"""Get real GPU status from nvidia-smi"""
try:
# Parse nvidia-smi output
result = subprocess.run(['nvidia-smi', '--query-gpu=utilization.gpu,temperature.gpu,power.draw,memory.used,memory.total,performance_state', '--format=csv,noheader,nounits'],
capture_output=True, text=True)
if result.returncode == 0:
values = result.stdout.strip().split(', ')
gpu_data = {
'utilization': int(values[0]),
'temperature': int(values[1]),
'power_usage': float(values[2]),
'memory_used': float(values[3]) / 1024, # Convert MB to GB
'memory_total': float(values[4]) / 1024,
'performance_state': values[5],
'timestamp': datetime.now().isoformat()
}
self.send_json_response(gpu_data)
else:
# Fallback to mock data
self.send_json_response({
'utilization': 0,
'temperature': 43,
'power_usage': 18,
'memory_used': 2.9,
'memory_total': 16,
'performance_state': 'P8',
'timestamp': datetime.now().isoformat()
})
except Exception as e:
self.send_json_response({'error': str(e)}, 500)
def get_mining_jobs(self):
"""Get active mining jobs from the miner service"""
try:
# Connect to miner service via socket or API
# For now, simulate with mock data
jobs = [
{
'id': 'job_12345',
'name': 'Matrix Computation',
'progress': 85,
'status': 'running',
'started_at': (datetime.now() - timedelta(minutes=10)).isoformat(),
'estimated_completion': (datetime.now() + timedelta(minutes=2)).isoformat()
},
{
'id': 'job_12346',
'name': 'Hash Validation',
'progress': 42,
'status': 'running',
'started_at': (datetime.now() - timedelta(minutes=5)).isoformat(),
'estimated_completion': (datetime.now() + timedelta(minutes=7)).isoformat()
}
]
self.send_json_response(jobs)
except Exception as e:
self.send_json_response({'error': str(e)}, 500)
def get_statistics(self):
"""Get mining statistics"""
stats = {
'total_jobs_completed': random.randint(1200, 1300),
'average_job_time': round(random.uniform(10, 15), 1),
'success_rate': round(random.uniform(95, 99), 1),
'total_earned_btc': round(random.uniform(0.004, 0.005), 4),
'total_earned_aitbc': random.randint(100, 200),
'uptime_hours': 24,
'hash_rate': round(random.uniform(45, 55), 1), # MH/s
'efficiency': round(random.uniform(0.8, 1.2), 2) # W/MH
}
self.send_json_response(stats)
def get_services(self):
"""Get available mining services"""
services = [
{
'name': 'GPU Computing',
'description': 'CUDA cores available for computation',
'status': 'active',
'capacity': '100%',
'utilization': 65
},
{
'name': 'Parallel Processing',
'description': 'Multi-threaded job execution',
'status': 'active',
'capacity': '8 threads',
'utilization': 45
},
{
'name': 'Hash Generation',
'description': 'Proof-of-work computation',
'status': 'standby',
'capacity': '50 MH/s',
'utilization': 0
},
{
'name': 'AI Model Training',
'description': 'Machine learning operations',
'status': 'available',
'capacity': '16GB VRAM',
'utilization': 0
},
{
'name': 'Blockchain Validation',
'description': 'AITBC block validation',
'status': 'active',
'capacity': '1000 tx/s',
'utilization': 23
},
{
'name': 'Data Processing',
'description': 'Large dataset processing',
'status': 'available',
'capacity': '500GB/hour',
'utilization': 0
}
]
self.send_json_response(services)
def serve_dashboard(self):
"""Serve the dashboard HTML"""
try:
with open('index.html', 'r') as f:
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
self.wfile.write(f.read().encode())
except FileNotFoundError:
self.send_error(404, 'Dashboard not found')
def run_server(port=8080):
"""Run the miner dashboard server"""
server = HTTPServer(('localhost', port), MinerDashboardHandler)
print(f"""
╔═══════════════════════════════════════╗
║ AITBC Miner Dashboard Server ║
╠═══════════════════════════════════════╣
║ Dashboard running at: ║
║ http://localhost:{port}
║ ║
║ GPU Monitoring Active! ║
║ Real-time Mining Status ║
╚═══════════════════════════════════════╝
""")
server.serve_forever()
if __name__ == "__main__":
run_server()