www/esp_devices.php

138 lines
6.6 KiB
PHP

<?php
session_start();
if (empty($_SESSION['loggedin'])) { header('Location: index.php'); exit; }
define('PMX_API', 'http://192.168.10.106:8765/?key=esp_api_xupas_2025');
function pmx_get(): array {
$ch = curl_init(PMX_API.'&action=list');
curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>8]);
$r = json_decode(curl_exec($ch),true); curl_close($ch);
return $r['devices'] ?? [];
}
function pmx_post(array $data): array {
$ch = curl_init(PMX_API);
curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>http_build_query($data),CURLOPT_TIMEOUT=>8]);
$r = json_decode(curl_exec($ch),true); curl_close($ch);
return $r ?? [];
}
$notice = ''; $error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$uid = preg_replace('/[^0-9A-Fa-f]/', '', $_POST['uid'] ?? '');
if (!$uid) { $error = 'UID inválido.'; }
else {
$res = pmx_post($_POST);
if (!empty($res['ok'])) $notice = "[{$uid}] {$_POST['action']} OK";
else $error = $res['error'] ?? 'Erro';
}
$qs = $notice ? '?ok='.urlencode($notice) : ($error ? '?err='.urlencode($error) : '');
header("Location: esp_devices.php$qs"); exit;
}
if (isset($_GET['ok'])) $notice = htmlspecialchars($_GET['ok']);
if (isset($_GET['err'])) $error = htmlspecialchars($_GET['err']);
$devices = pmx_get();
function h($s) { return htmlspecialchars((string)$s, ENT_QUOTES); }
?>
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ESP Devices — Proxmox</title>
<style>
* { box-sizing:border-box; margin:0; padding:0; }
body { background:#0d1117; color:#e6edf3; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:14px; }
.header { background:#161b22; border-bottom:1px solid #21262d; padding:14px 24px; display:flex; align-items:center; gap:16px; }
.header a { color:#58a6ff; text-decoration:none; font-size:13px; }
.header h1 { font-size:16px; font-weight:600; flex:1; }
.wrap { max-width:1200px; margin:0 auto; padding:24px; }
.flash-ok { background:#0d4f2a; color:#3fb950; padding:10px 16px; border-radius:6px; margin-bottom:16px; }
.flash-err { background:#4f1010; color:#da3633; padding:10px 16px; border-radius:6px; margin-bottom:16px; }
table { width:100%; border-collapse:collapse; font-size:13px; }
th { background:#1e2733; padding:10px 12px; text-align:left; color:#aaa; font-weight:normal; }
td { padding:9px 12px; border-bottom:1px solid #1e2733; vertical-align:middle; }
tr:hover td { background:#111822; }
.badge { display:inline-block; padding:2px 8px; border-radius:4px; font-size:11px; }
.badge-ok { background:#0d4f2a; color:#3fb950; }
.badge-block { background:#4f1010; color:#da3633; }
.btn { display:inline-block; padding:4px 9px; border-radius:4px; border:none; cursor:pointer; font-size:12px; }
.btn:hover { filter:brightness(1.3); }
.btn-green { background:#1a4a1a; color:#3fb950; }
.btn-red { background:#4f1010; color:#da3633; }
.btn-grey { background:#2a2a2a; color:#ccc; }
.btn-blue { background:#0d2a4f; color:#58a6ff; }
.btn-orange { background:#4f3210; color:#d29922; }
.btn-purple { background:#2d1a4f; color:#bc8cff; }
.uid { font-family:monospace; }
.ago { color:#666; font-size:11px; }
form { display:inline; }
</style>
</head>
<body>
<div class="header">
<a href="index.php">← Painel</a>
<h1>ESP Devices <span style="color:#bc8cff;font-size:13px;font-weight:400">— Proxmox broker</span></h1>
<span style="color:#666;font-size:12px"><?= count($devices) ?> dispositivos</span>
</div>
<div class="wrap">
<?php if ($notice): ?><div class="flash-ok"><?= $notice ?></div><?php endif; ?>
<?php if ($error): ?><div class="flash-err"><?= $error ?></div><?php endif; ?>
<?php if (!$devices): ?>
<p style="color:#666;margin-top:20px">Sem dispositivos ou erro a ligar ao broker Proxmox.</p>
<?php else: ?>
<table>
<thead><tr><th>UID</th><th>Broker atual</th><th>Estado</th><th>Último contacto</th><th>Heap</th><th>RSSI</th><th>Ações</th></tr></thead>
<tbody>
<?php foreach ($devices as $d):
$uid = $d['uid'];
$blocked= (bool)$d['blocked'];
$broker = $d['current_broker'] ?? '—';
$last = $d['last_seen'] ?? '-';
$ago = '-';
if ($last && $last !== '-') {
$diff = time() - strtotime($last);
if ($diff < 60) $ago = $diff.'s atrás';
else if ($diff < 3600) $ago = round($diff/60).'min atrás';
else $ago = round($diff/3600).'h atrás';
}
?>
<tr>
<td><span class="uid"><?= h($uid) ?></span></td>
<td style="font-size:12px;color:var(--muted,#8b949e)"><?= h($broker) ?></td>
<td><?php if ($blocked): ?>
<span class="badge badge-block">bloqueado</span>
<?php else: ?>
<span class="badge badge-ok">aprovado</span>
<?php endif; ?></td>
<td><?= h($last) ?><br><span class="ago"><?= $ago ?></span></td>
<td style="color:#666;font-size:12px"><?= $d['heap'] ? number_format((int)$d['heap']) : '—' ?></td>
<td style="color:#666;font-size:12px"><?= $d['rssi'] ? $d['rssi'].' dBm' : '—' ?></td>
<td style="white-space:nowrap">
<?php if ($blocked): ?>
<form method="post"><input type="hidden" name="uid" value="<?= h($uid) ?>"><input type="hidden" name="action" value="approve"><button class="btn btn-green">Aprovar</button></form>
<?php else: ?>
<form method="post"><input type="hidden" name="uid" value="<?= h($uid) ?>"><input type="hidden" name="action" value="block"><button class="btn btn-red">Bloquear</button></form>
<?php endif; ?>
<?php foreach ([['REBOOT','btn-orange','Reboot'],['STATUS','btn-grey','Status'],['SWITCH_PRIMARY','btn-blue','→Main'],['REJOIN','btn-grey','Rejoin']] as [$c,$cl,$lb]): ?>
<form method="post"><input type="hidden" name="uid" value="<?= h($uid) ?>"><input type="hidden" name="action" value="cmd"><input type="hidden" name="cmd" value="<?= $c ?>"><button class="btn <?= $cl ?>"><?= $lb ?></button></form>
<?php endforeach; ?>
<form method="post"><input type="hidden" name="uid" value="<?= h($uid) ?>"><input type="hidden" name="action" value="switch_pair"><input type="hidden" name="pair" value="0"><button class="btn btn-blue">→xpto</button></form>
<form method="post"><input type="hidden" name="uid" value="<?= h($uid) ?>"><input type="hidden" name="action" value="switch_pair"><input type="hidden" name="pair" value="1"><button class="btn btn-purple">→xupas</button></form>
<form method="post" onsubmit="return confirm('Remover?')"><input type="hidden" name="uid" value="<?= h($uid) ?>"><input type="hidden" name="action" value="delete"><button class="btn btn-red">✕</button></form>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</body>
</html>