127 lines
4.2 KiB
PHP
127 lines
4.2 KiB
PHP
|
|
<?php
|
||
|
|
declare(strict_types=1);
|
||
|
|
require_once __DIR__ . '/vendor/autoload.php';
|
||
|
|
|
||
|
|
use PhpMqtt\Client\MqttClient;
|
||
|
|
use PhpMqtt\Client\ConnectionSettings;
|
||
|
|
|
||
|
|
// Configuração da BD
|
||
|
|
$dbHost="localhost"; $dbName="cagalhao"; $dbUser="master"; $dbPass="master";
|
||
|
|
try {
|
||
|
|
$db = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8",$dbUser,$dbPass);
|
||
|
|
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||
|
|
} catch(Throwable $e) {
|
||
|
|
die("Erro na BD: " . $e->getMessage());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Configuração do MQTT
|
||
|
|
$mqttHost='xupas.mooo.com'; $mqttPort=1883; $mqttUser='xupa'; $mqttPass='xupa';
|
||
|
|
|
||
|
|
// Função para enviar comando
|
||
|
|
function sendMqttCommand(string $espId, int $pin, int $value): bool {
|
||
|
|
global $mqttHost, $mqttPort, $mqttUser, $mqttPass;
|
||
|
|
|
||
|
|
try {
|
||
|
|
$clientId = "gpio-panel-".uniqid();
|
||
|
|
$settings = (new ConnectionSettings())
|
||
|
|
->setUsername($mqttUser)
|
||
|
|
->setPassword($mqttPass)
|
||
|
|
->setKeepAliveInterval(10)
|
||
|
|
->setConnectTimeout(3)
|
||
|
|
->setSocketTimeout(3);
|
||
|
|
|
||
|
|
$mqtt = new MqttClient($mqttHost, $mqttPort, $clientId);
|
||
|
|
$mqtt->connect($settings, true);
|
||
|
|
|
||
|
|
$payload = json_encode([
|
||
|
|
'cmd' => 'GPIO',
|
||
|
|
'pin' => $pin,
|
||
|
|
'value' => $value
|
||
|
|
]);
|
||
|
|
|
||
|
|
$topic = "esp/{$espId}/cmd";
|
||
|
|
$mqtt->publish($topic, $payload, 0, false);
|
||
|
|
$mqtt->disconnect();
|
||
|
|
return true;
|
||
|
|
} catch (Throwable $e) {
|
||
|
|
error_log("MQTT-ERR) " . $e->getMessage());
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Processar pedidos
|
||
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
|
|
$esp = $_POST['esp'] ?? '';
|
||
|
|
$pin = intval($_POST['pin'] ?? -1);
|
||
|
|
$val = intval($_POST['value'] ?? -1);
|
||
|
|
|
||
|
|
if ($esp && $pin >= 0 && ($val === 0 || $val === 1)) {
|
||
|
|
$ok = sendMqttCommand($esp, $pin, $val);
|
||
|
|
if ($ok) {
|
||
|
|
$msg = "✅ Comando enviado: {$esp} → Pino {$pin} → ".($val ? "ON" : "OFF");
|
||
|
|
} else {
|
||
|
|
$msg = "❌ Falha ao enviar comando para {$esp}";
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
$msg = "⚠️ Parâmetros inválidos";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Buscar ESPs registados
|
||
|
|
$stmt = $db->query("SELECT uid, online, last_seen FROM contadores ORDER BY uid ASC");
|
||
|
|
$esps = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
|
|
?>
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="pt">
|
||
|
|
<head>
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<title>Controle GPIO via MQTT</title>
|
||
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
|
||
|
|
</head>
|
||
|
|
<body class="bg-dark text-light">
|
||
|
|
<div class="container py-4">
|
||
|
|
<h1 class="mb-4">⚡ Controle de GPIO (MQTT)</h1>
|
||
|
|
|
||
|
|
<?php if (!empty($msg)): ?>
|
||
|
|
<div class="alert alert-info"><?= htmlspecialchars($msg) ?></div>
|
||
|
|
<?php endif; ?>
|
||
|
|
|
||
|
|
<table class="table table-dark table-striped table-bordered align-middle">
|
||
|
|
<thead>
|
||
|
|
<tr>
|
||
|
|
<th>ESP</th>
|
||
|
|
<th>Status</th>
|
||
|
|
<th>Último Sinal</th>
|
||
|
|
<th>Pino</th>
|
||
|
|
<th>Ação</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
<?php foreach ($esps as $esp): ?>
|
||
|
|
<tr>
|
||
|
|
<td><?= htmlspecialchars($esp['uid']) ?></td>
|
||
|
|
<td>
|
||
|
|
<?php if ($esp['online']): ?>
|
||
|
|
<span class="badge bg-success">Online</span>
|
||
|
|
<?php else: ?>
|
||
|
|
<span class="badge bg-danger">Offline</span>
|
||
|
|
<?php endif; ?>
|
||
|
|
</td>
|
||
|
|
<td><?= htmlspecialchars($esp['last_seen']) ?></td>
|
||
|
|
<td>
|
||
|
|
<form method="post" class="d-flex gap-2">
|
||
|
|
<input type="hidden" name="esp" value="<?= htmlspecialchars($esp['uid']) ?>">
|
||
|
|
<input type="number" name="pin" min="0" max="16" class="form-control form-control-sm" required>
|
||
|
|
</td>
|
||
|
|
<td>
|
||
|
|
<button type="submit" name="value" value="1" class="btn btn-success btn-sm">ON</button>
|
||
|
|
<button type="submit" name="value" value="0" class="btn btn-danger btn-sm">OFF</button>
|
||
|
|
</form>
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
<?php endforeach; ?>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
</body>
|
||
|
|
</html>
|