# Conecte-se ao seu servidor via SSH ssh usuario@seu-dominio.com # Crie a estrutura de pastas mkdir -p /var/www/iot-esp32/{public,api,logs,ssl,config} cd /var/www/iot-esp32 # Estrutura final: # /var/www/iot-esp32/ # ├── public/ # Interface web # │ ├── index.html # │ ├── dashboard.html # │ └── assets/ # ├── api/ # Backend (Node.js/Python) # │ ├── server.js # │ └── package.json # ├── logs/ # Logs do sistema # ├── ssl/ # Certificados SSL # └── config/ # Configurações # └── nginx.conf 2. Opção 1: API REST + MQTT (Recomendado) Backend Node.js com MQTT bash cd /var/www/iot-esp32/api npm init -y npm install express mqtt cors dotenv server.js: javascript require('dotenv').config(); const express = require('express'); const mqtt = require('mqtt'); const cors = require('cors'); const app = express(); app.use(cors()); app.use(express.json()); app.use(express.static('../public')); // Conecta ao broker MQTT (Mosquitto local) const mqttClient = mqtt.connect('mqtt://localhost:1883', { username: process.env.MQTT_USER, password: process.env.MQTT_PASS }); mqttClient.on('connect', () => { console.log('MQTT Conectado'); mqttClient.subscribe('esp32/+/status'); // Recebe status dos dispositivos }); // Armazena estado dos dispositivos let dispositivos = {}; mqttClient.on('message', (topic, message) => { const deviceId = topic.split('/')[1]; dispositivos[deviceId] = JSON.parse(message.toString()); }); // API REST app.get('/api/dispositivos', (req, res) => { res.json(dispositivos); }); app.post('/api/dispositivo/:id/comando', (req, res) => { const { id } = req.params; const { comando, valor } = req.body; // Publica comando MQTT para o ESP32 mqttClient.publish(`esp32/${id}/comando`, JSON.stringify({ comando: comando, valor: valor })); res.json({ status: 'ok', mensagem: 'Comando enviado' }); }); // Autenticação simples app.use('/api', (req, res, next) => { const token = req.headers['authorization']; if (token === process.env.API_TOKEN) { next(); } else { res.status(401).json({ erro: 'Não autorizado' }); } }); app.listen(3000, () => console.log('API rodando na porta 3000')); .env: env MQTT_USER=seu_usuario MQTT_PASS=sua_senha API_TOKEN=token_secreto_esp32 Configurar PM2 (Gerenciador de Processos) bash npm install -g pm2 pm2 start server.js --name iot-api pm2 save pm2 startup 3. Instalar e Configurar Mosquitto MQTT bash # Instalar Mosquitto sudo apt update sudo apt install mosquitto mosquitto-clients -y # Configurar senha sudo mosquitto_passwd -c /etc/mosquitto/passwd seu_usuario # Digite a senha quando solicitado # Editar configuração sudo nano /etc/mosquitto/conf.d/default.conf default.conf: conf listener 1883 allow_anonymous false password_file /etc/mosquitto/passwd # Para WebSockets (interface web) listener 9001 protocol websockets bash sudo systemctl restart mosquitto sudo systemctl enable mosquitto 4. Configurar Nginx como Proxy Reverso bash sudo apt install nginx certbot python3-certbot-nginx -y /etc/nginx/sites-available/iot-esp32: nginx server { listen 80; server_name iot.seudominio.com; # Redireciona para HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name iot.seudominio.com; # SSL (será configurado pelo Certbot depois) ssl_certificate /etc/letsencrypt/live/iot.seudominio.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/iot.seudominio.com/privkey.pem; # Segurança add_header X-Frame-Options "SAMEORIGIN"; add_header X-Content-Type-Options "nosniff"; # Dashboard web location / { root /var/www/iot-esp32/public; index index.html; try_files $uri $uri/ =404; } # API location /api/ { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Real-IP $remote_addr; } # WebSocket MQTT location /mqtt { proxy_pass http://localhost:9001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } bash # Ativar o site sudo ln -s /etc/nginx/sites-available/iot-esp32 /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx # Obter certificado SSL sudo certbot --nginx -d iot.seudominio.com 5. Código do ESP32 cpp #include #include #include // Configurações const char* ssid = "SUA_REDE_WIFI"; const char* password = "SUA_SENHA_WIFI"; const char* mqtt_server = "iot.seudominio.com"; // Seu domínio! const int mqtt_port = 1883; const char* mqtt_user = "seu_usuario"; const char* mqtt_pass = "sua_senha"; const char* device_id = "esp32_001"; WiFiClient espClient; PubSubClient client(espClient); // Pinos const int ledPin = 2; const int sensorPin = 34; void callback(char* topic, byte* payload, unsigned int length) { // Converte payload para string char message[length + 1]; memcpy(message, payload, length); message[length] = '\0'; // Parse JSON StaticJsonDocument<200> doc; DeserializationError error = deserializeJson(doc, message); if (!error) { const char* comando = doc["comando"]; int valor = doc["valor"]; if (strcmp(comando, "led") == 0) { digitalWrite(ledPin, valor); enviarStatus(); // Confirma estado } } } void enviarStatus() { StaticJsonDocument<200> doc; doc["led"] = digitalRead(ledPin); doc["sensor"] = analogRead(sensorPin); doc["wifi"] = WiFi.RSSI(); doc["uptime"] = millis() / 1000; char buffer[256]; serializeJson(doc, buffer); String topico = String("esp32/") + device_id + "/status"; client.publish(topico.c_str(), buffer); } void reconectarMQTT() { while (!client.connected()) { Serial.print("Conectando ao MQTT..."); if (client.connect(device_id, mqtt_user, mqtt_pass)) { Serial.println("Conectado!"); // Inscreve no tópico de comandos String topico = String("esp32/") + device_id + "/comando"; client.subscribe(topico.c_str()); enviarStatus(); // Envia status inicial } else { Serial.print("Falha, rc="); Serial.print(client.state()); delay(5000); } } } void setup() { Serial.begin(115200); pinMode(ledPin, OUTPUT); // WiFi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println("\nWiFi Conectado!"); // MQTT client.setServer(mqtt_server, mqtt_port); client.setCallback(callback); // Envia status a cada 30 segundos xTaskCreate([](void* param) { while(1) { if (client.connected()) { ((PubSubClient*)param)->loop(); enviarStatus(); } vTaskDelay(30000 / portTICK_PERIOD_MS); } }, "StatusTask", 4096, &client, 1, NULL); } void loop() { if (!client.connected()) { reconectarMQTT(); } client.loop(); } 6. Interface Web Dashboard /var/www/iot-esp32/public/index.html: html IoT Dashboard

🏠 Controle ESP32

Dispositivo: ESP32_001

Carregando...
Sensor: --
WiFi: --
7. Testar Tudo bash # No servidor, testar MQTT mosquitto_sub -h localhost -u seu_usuario -P sua_senha -t "esp32/+/status" # Em outro terminal, simular ESP32 mosquitto_pub -h localhost -u seu_usuario -P sua_senha \ -t "esp32/esp32_001/status" \ -m '{"led":1,"sensor":450,"wifi":-50,"uptime":3600}' # Testar API curl -X POST https://iot.seudominio.com/api/dispositivo/esp32_001/comando \ -H "Authorization: token_secreto_esp32" \ -H "Content-Type: application/json" \ -d '{"comando":"led","valor":1}' Resumo da Integração ESP32 → Publica status via MQTT para seu domínio Mosquitto → Broker MQTT no servidor Linux Node.js API → Converte HTTP ↔ MQTT Nginx → Proxy reverso com SSL Seu Domínio → Acessa de qualquer lugar com HTTPS Agora você acessa https://iot.seudominio.com e controla seu ESP32 de qualquer lugar do mundo! 🚀 Precisa de ajuda com alguma parte específica? meu servidor e apache Perfeito! Vamos adaptar toda a configuração para Apache. O Apache é igualmente poderoso e muito usado. Vou te mostrar a configuração completa. Estrutura de Pastas (com Apache) bash # Conecte ao servidor via SSH ssh usuario@seu-dominio.com # Criar estrutura de pastas sudo mkdir -p /var/www/iot-esp32/{public_html,api,logs,ssl,config} cd /var/www/iot-esp32 # Ajustar permissões sudo chown -R $USER:www-data /var/www/iot-esp32 sudo chmod -R 755 /var/www/iot-esp32 # Estrutura: # /var/www/iot-esp32/ # ├── public_html/ # Arquivos web (Apache serve daqui) # │ ├── index.html # │ ├── dashboard.html # │ └── assets/ # ├── api/ # Backend Node.js/Python # │ ├── server.js # │ └── package.json # ├── logs/ # Logs # ├── ssl/ # Certificados # └── config/ # Configurações 1. Instalar Pacotes Necessários bash # Atualizar sistema sudo apt update sudo apt upgrade -y # Apache e módulos necessários sudo apt install apache2 -y # Habilitar módulos importantes sudo a2enmod proxy sudo a2enmod proxy_http sudo a2enmod proxy_wstunnel sudo a2enmod rewrite sudo a2enmod ssl sudo a2enmod headers # Mosquitto MQTT sudo apt install mosquitto mosquitto-clients -y # Node.js (para API) curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install nodejs -y # Certbot para SSL sudo apt install certbot python3-certbot-apache -y # PM2 para gerenciar processos sudo npm install -g pm2 2. Configurar Virtual Host no Apache Criar arquivo de configuração: bash sudo nano /etc/apache2/sites-available/iot-esp32.conf iot-esp32.conf (Configuração completa): apache ServerName iot.seudominio.com ServerAdmin webmaster@seudominio.com DocumentRoot /var/www/iot-esp32/public_html # Logs ErrorLog /var/www/iot-esp32/logs/error.log CustomLog /var/www/iot-esp32/logs/access.log combined # Redirecionar para HTTPS (após configurar SSL, descomente) # RewriteEngine On # RewriteCond %{HTTPS} off # RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] # Configurações do diretório Options Indexes FollowSymLinks AllowOverride All Require all granted # API - Proxy reverso para Node.js ProxyPreserveHost On ProxyPass /api/ http://localhost:3000/ ProxyPassReverse /api/ http://localhost:3000/ # WebSocket para MQTT ProxyPass /mqtt ws://localhost:9001/ ProxyPassReverse /mqtt ws://localhost:9001/ # Headers de segurança Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set X-XSS-Protection "1; mode=block" # Configuração HTTPS (após obter certificado) ServerName iot.seudominio.com ServerAdmin webmaster@seudominio.com DocumentRoot /var/www/iot-esp32/public_html # SSL SSLEngine on SSLCertificateFile /etc/letsencrypt/live/iot.seudominio.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/iot.seudominio.com/privkey.pem # Logs ErrorLog /var/www/iot-esp32/logs/ssl_error.log CustomLog /var/www/iot-esp32/logs/ssl_access.log combined # Configurações do diretório Options Indexes FollowSymLinks AllowOverride All Require all granted # API - Proxy reverso ProxyPreserveHost On ProxyPass /api/ http://localhost:3000/ ProxyPassReverse /api/ http://localhost:3000/ # WebSocket para MQTT ProxyPass /mqtt ws://localhost:9001/ ProxyPassReverse /mqtt ws://localhost:9001/ # Headers de segurança Header always set Strict-Transport-Security "max-age=31536000" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" 3. Ativar o Site bash # Habilitar o site sudo a2ensite iot-esp32.conf # Desabilitar site padrão (opcional) sudo a2dissite 000-default.conf # Verificar configuração sudo apache2ctl configtest # Recarregar Apache sudo systemctl reload apache2 sudo systemctl restart apache2 4. Configurar Mosquitto MQTT bash # Configurar autenticação sudo mosquitto_passwd -c /etc/mosquitto/passwd seu_usuario # Digite a senha quando solicitado # Criar arquivo de configuração sudo nano /etc/mosquitto/conf.d/iot.conf iot.conf: conf # Listener padrão MQTT listener 1883 protocol mqtt allow_anonymous false password_file /etc/mosquitto/passwd # WebSocket para interface web listener 9001 protocol websockets allow_anonymous false password_file /etc/mosquitto/passwd # Logs log_dest file /var/log/mosquitto/mosquitto.log log_type all bash # Reiniciar Mosquitto sudo systemctl restart mosquitto sudo systemctl enable mosquitto # Testar mosquitto_sub -h localhost -u seu_usuario -P sua_senha -t "test/topic" -v 5. Backend API (Node.js) bash cd /var/www/iot-esp32/api npm init -y npm install express mqtt cors dotenv helmet server.js: javascript require('dotenv').config(); const express = require('express'); const mqtt = require('mqtt'); const cors = require('cors'); const helmet = require('helmet'); const app = express(); // Middlewares app.use(helmet()); app.use(cors()); app.use(express.json()); // Conectar ao broker MQTT local const mqttClient = mqtt.connect('mqtt://localhost:1883', { username: process.env.MQTT_USER || 'seu_usuario', password: process.env.MQTT_PASS || 'sua_senha', clientId: 'api_server_' + Math.random().toString(16).slice(2) }); // Armazenar estado dos dispositivos const dispositivos = new Map(); mqttClient.on('connect', () => { console.log('✅ Conectado ao MQTT'); mqttClient.subscribe('esp32/+/status'); }); mqttClient.on('message', (topic, message) => { const deviceId = topic.split('/')[1]; try { const data = JSON.parse(message.toString()); data.lastSeen = new Date().toISOString(); dispositivos.set(deviceId, data); console.log(`📡 Status recebido de ${deviceId}:`, data); } catch (e) { console.error('Erro ao parsear mensagem:', e); } }); // Rotas da API // Listar todos os dispositivos app.get('/api/dispositivos', (req, res) => { const lista = Array.from(dispositivos.entries()).map(([id, data]) => ({ id, ...data })); res.json(lista); }); // Status de um dispositivo específico app.get('/api/dispositivo/:id', (req, res) => { const dispositivo = dispositivos.get(req.params.id); if (dispositivo) { res.json({ id: req.params.id, ...dispositivo }); } else { res.status(404).json({ erro: 'Dispositivo não encontrado' }); } }); // Enviar comando para dispositivo app.post('/api/dispositivo/:id/comando', (req, res) => { const { id } = req.params; const { comando, valor } = req.body; if (!comando) { return res.status(400).json({ erro: 'Comando é obrigatório' }); } const topico = `esp32/${id}/comando`; const payload = JSON.stringify({ comando, valor: valor || 0, timestamp: Date.now() }); mqttClient.publish(topico, payload, { qos: 1 }, (err) => { if (err) { console.error('Erro ao publicar:', err); res.status(500).json({ erro: 'Falha ao enviar comando' }); } else { console.log(`📤 Comando enviado para ${id}:`, { comando, valor }); res.json({ status: 'ok', mensagem: `Comando "${comando}" enviado para ${id}` }); } }); }); // Rota de health check app.get('/api/health', (req, res) => { res.json({ status: 'online', uptime: process.uptime(), dispositivos: dispositivos.size, mqtt: mqttClient.connected }); }); // Iniciar servidor const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`🚀 API rodando em http://localhost:${PORT}`); }); .env: env PORT=3000 MQTT_USER=seu_usuario MQTT_PASS=sua_senha API_TOKEN=token_super_secreto_2024 6. Configurar PM2 (Gerenciador de Processos) bash # Iniciar API com PM2 cd /var/www/iot-esp32/api pm2 start server.js --name iot-api --time # Configurar para iniciar com o sistema pm2 startup pm2 save # Comandos úteis pm2 status # Ver status pm2 logs iot-api # Ver logs pm2 restart iot-api # Reiniciar pm2 stop iot-api # Parar 7. Arquivo .htaccess para Segurança Extra /var/www/iot-esp32/public_html/.htaccess: apache # Proteger arquivos sensíveis Order allow,deny Deny from all # Desabilitar listagem de diretórios Options -Indexes # Forçar HTTPS RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L] # Headers de segurança Header set X-Content-Type-Options "nosniff" Header set X-Frame-Options "SAMEORIGIN" Header set X-XSS-Protection "1; mode=block" Header set Referrer-Policy "strict-origin-when-cross-origin" # Compressão GZIP AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript AddOutputFilterByType DEFLATE application/javascript application/json # Cache do navegador ExpiresActive On ExpiresByType text/html "access plus 1 hour" ExpiresByType text/css "access plus 1 week" ExpiresByType text/javascript "access plus 1 week" ExpiresByType image/png "access plus 1 month" ExpiresByType image/jpg "access plus 1 month" 8. Interface Web /var/www/iot-esp32/public_html/index.html: html IoT Dashboard - ESP32

🏠 Controle ESP32

Dispositivo: ESP32_001

Desconectado
Sensor: --
Sinal WiFi: -- dBm
Uptime: --
Última atualização: --
9. Código do ESP32 O código do ESP32 é o mesmo da resposta anterior, mas ajuste o servidor MQTT: cpp // No ESP32, configure: const char* mqtt_server = "iot.seudominio.com"; // Seu domínio const int mqtt_port = 1883; // Porta MQTT const char* mqtt_user = "seu_usuario"; const char* mqtt_pass = "sua_senha"; 10. Obter Certificado SSL bash # Parar Apache temporariamente (opcional) sudo systemctl stop apache2 # Obter certificado sudo certbot --apache -d iot.seudominio.com # Seguir as ja tenho a pasta que irei utlizar /sites/xkbitcoin/video Perfeito! Vamos adaptar tudo para usar sua pasta existente /sites/xkbitcoin/video. Vou te mostrar a configuração completa usando esse caminho. 1. Estrutura dentro da sua pasta existente bash # Acesse sua pasta cd /sites/xkbitcoin/video # Criar subpastas para o projeto IoT mkdir -p iot/{public_html,api,logs,config} cd iot # Estrutura final: # /sites/xkbitcoin/video/iot/ # ├── public_html/ # Interface web # │ ├── index.html # │ └── assets/ # ├── api/ # Backend Node.js # │ ├── server.js # │ ├── package.json # │ └── .env # ├── logs/ # Logs específicos # └── config/ # Configurações 2. Configurar Virtual Host no Apache Criar arquivo de configuração: bash sudo nano /etc/apache2/sites-available/xkbitcoin-iot.conf xkbitcoin-iot.conf: apache ServerName iot.xkbitcoin.com ServerAdmin webmaster@xkbitcoin.com # Usando sua pasta existente! DocumentRoot /sites/xkbitcoin/video/iot/public_html # Logs na sua pasta ErrorLog /sites/xkbitcoin/video/iot/logs/error.log CustomLog /sites/xkbitcoin/video/iot/logs/access.log combined # Configurações do diretório Options Indexes FollowSymLinks AllowOverride All Require all granted # API - Proxy reverso para Node.js (porta 3000) ProxyPreserveHost On ProxyPass /api/ http://localhost:3000/ ProxyPassReverse /api/ http://localhost:3000/ # WebSocket para MQTT ProxyPass /mqtt ws://localhost:9001/ ProxyPassReverse /mqtt ws://localhost:9001/ # Headers de segurança Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" # Versão HTTPS (após certificado SSL) ServerName iot.xkbitcoin.com DocumentRoot /sites/xkbitcoin/video/iot/public_html SSLEngine on SSLCertificateFile /etc/letsencrypt/live/iot.xkbitcoin.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/iot.xkbitcoin.com/privkey.pem ErrorLog /sites/xkbitcoin/video/iot/logs/ssl_error.log CustomLog /sites/xkbitcoin/video/iot/logs/ssl_access.log combined Options Indexes FollowSymLinks AllowOverride All Require all granted ProxyPreserveHost On ProxyPass /api/ http://localhost:3000/ ProxyPassReverse /api/ http://localhost:3000/ ProxyPass /mqtt ws://localhost:9001/ ProxyPassReverse /mqtt ws://localhost:9001/ Header always set Strict-Transport-Security "max-age=31536000" Header always set X-Frame-Options "SAMEORIGIN" 3. Ativar o Site e Ajustar Permissões bash # Ativar o site sudo a2ensite xkbitcoin-iot.conf # Ajustar permissões da sua pasta sudo chown -R $USER:www-data /sites/xkbitcoin/video/iot sudo chmod -R 755 /sites/xkbitcoin/video/iot # Permissão especial para logs sudo chmod 775 /sites/xkbitcoin/video/iot/logs # Verificar configuração do Apache sudo apache2ctl configtest # Recarregar Apache sudo systemctl reload apache2 4. Backend API na sua pasta bash cd /sites/xkbitcoin/video/iot/api # Inicializar Node.js npm init -y npm install express mqtt cors dotenv helmet package.json (adicione o script start): json { "name": "xkbitcoin-iot-api", "version": "1.0.0", "description": "API IoT para ESP32", "main": "server.js", "scripts": { "start": "node server.js", "dev": "nodemon server.js" }, "dependencies": { "cors": "^2.8.5", "dotenv": "^16.3.1", "express": "^4.18.2", "helmet": "^7.1.0", "mqtt": "^5.3.0" } } server.js: javascript require('dotenv').config(); const express = require('express'); const mqtt = require('mqtt'); const cors = require('cors'); const helmet = require('helmet'); const path = require('path'); const app = express(); // Middlewares app.use(helmet()); app.use(cors()); app.use(express.json()); // Servir arquivos estáticos da sua pasta app.use(express.static(path.join(__dirname, '../public_html'))); // Conectar ao broker MQTT local const mqttClient = mqtt.connect('mqtt://localhost:1883', { username: process.env.MQTT_USER || 'seu_usuario', password: process.env.MQTT_PASS || 'sua_senha', clientId: 'api_xkbitcoin_' + Math.random().toString(16).slice(2) }); // Armazenar estado dos dispositivos const dispositivos = new Map(); mqttClient.on('connect', () => { console.log('✅ Conectado ao MQTT'); mqttClient.subscribe('esp32/+/status'); console.log('📡 Ouvindo tópicos: esp32/+/status'); }); mqttClient.on('message', (topic, message) => { const deviceId = topic.split('/')[1]; try { const data = JSON.parse(message.toString()); data.lastSeen = new Date().toISOString(); data.topic = topic; dispositivos.set(deviceId, data); console.log(`📡 Status de ${deviceId}:`, JSON.stringify(data)); } catch (e) { console.error('❌ Erro ao processar mensagem:', e.message); } }); mqttClient.on('error', (error) => { console.error('❌ Erro MQTT:', error); }); // Rotas da API app.get('/api/dispositivos', (req, res) => { const lista = Array.from(dispositivos.entries()).map(([id, data]) => ({ id, ...data })); res.json({ total: lista.length, dispositivos: lista }); }); app.get('/api/dispositivo/:id', (req, res) => { const dispositivo = dispositivos.get(req.params.id); if (dispositivo) { res.json({ id: req.params.id, ...dispositivo }); } else { res.status(404).json({ erro: 'Dispositivo não encontrado', id: req.params.id }); } }); app.post('/api/dispositivo/:id/comando', (req, res) => { const { id } = req.params; const { comando, valor } = req.body; if (!comando) { return res.status(400).json({ erro: 'Comando é obrigatório' }); } const topico = `esp32/${id}/comando`; const payload = JSON.stringify({ comando, valor: valor || 0, timestamp: Date.now(), origem: 'web_dashboard' }); mqttClient.publish(topico, payload, { qos: 1 }, (err) => { if (err) { console.error('❌ Erro ao publicar:', err); res.status(500).json({ erro: 'Falha ao enviar comando' }); } else { console.log(`📤 Comando enviado para ${id}:`, { comando, valor }); res.json({ status: 'ok', mensagem: `Comando "${comando}" enviado com sucesso`, dispositivo: id, comando: comando }); } }); }); app.get('/api/health', (req, res) => { res.json({ status: 'online', servidor: 'xkbitcoin-iot', uptime: process.uptime(), dispositivos_ativos: dispositivos.size, mqtt_conectado: mqttClient.connected, timestamp: new Date().toISOString() }); }); // Rota principal - Dashboard app.get('/', (req, res) => { res.sendFile(path.join(__dirname, '../public_html/index.html')); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`🚀 API IoT rodando em http://localhost:${PORT}`); console.log(`📁 Servindo arquivos de: ${path.join(__dirname, '../public_html')}`); console.log(`🌐 Acesse: http://iot.xkbitcoin.com`); }); .env: env PORT=3000 MQTT_USER=seu_usuario_mqtt MQTT_PASS=sua_senha_mqtt API_TOKEN=xkbitcoin_token_secreto_2024 NODE_ENV=production 5. Instalar e Configurar Mosquitto bash # Instalar Mosquitto sudo apt install mosquitto mosquitto-clients -y # Configurar senha sudo mosquitto_passwd -c /etc/mosquitto/passwd seu_usuario # Configuração sudo nano /etc/mosquitto/conf.d/xkbitcoin.conf xkbitcoin.conf: conf # MQTT tradicional listener 1883 protocol mqtt allow_anonymous false password_file /etc/mosquitto/passwd # WebSocket para dashboard web listener 9001 protocol websockets allow_anonymous false password_file /etc/mosquitto/passwd # Logs na sua pasta log_dest file /sites/xkbitcoin/video/iot/logs/mosquitto.log log_type all bash sudo systemctl restart mosquitto 6. Interface Web na sua pasta /sites/xkbitcoin/video/iot/public_html/index.html: html XKBitcoin IoT - Controle ESP32

🏠 XKBitcoin IoT

Controle Remoto ESP32

Dispositivo: ESP32_001

Aguardando...
📊 Sensor
--
📶 WiFi
-- dBm
⏱️ Uptime
--
🕐 Último Status
--
7. Iniciar a API com PM2 bash cd /sites/xkbitcoin/video/iot/api # Iniciar com PM2 pm2 start server.js --name xkbitcoin-iot --time # Salvar configuração pm2 save # Configurar inicialização automática pm2 startup # Verificar status pm2 status pm2 logs xkbitcoin-iot 8. Criar .htaccess na sua pasta /sites/xkbitcoin/video/iot/public_html/.htaccess: apache RewriteEngine On # Forçar HTTPS RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L] # Redirecionar para dashboard DirectoryIndex index.html # Segurança Options -Indexes 9. Testar tudo bash # 1. Testar Mosquitto mosquitto_pub -h localhost -u seu_usuario -P sua_senha \ -t "esp32/esp32_001/status" \ -m '{"led":1,"sensor":450,"wifi":-50,"uptime":3600}' # 2. Testar API curl http://localhost:3000/api/dispositivos # 3. Testar via domínio curl http://iot.xkbitcoin.com/api/health # 4. Ver logs tail -f /sites/xkbitcoin/video/iot/logs/error.log pm2 logs xkbitcoin-iot 10. Código do ESP32 (resumo) cpp // Configurações para seu servidor const char* mqtt_server = "iot.xkbitcoin.com"; // Seu subdomínio const int mqtt_port = 1883; const char* mqtt_user = "seu_usuario"; const char* mqtt_pass = "sua_senha"; const char* device_id = "esp32_001"; // O resto do código é igual ao exemplo anterior // Publica em: esp32/esp32_001/status // Assina: esp32/esp32_001/comando Resumo das URLs Dashboard: http://iot.xkbitcoin.com (ou HTTPS depois) API: http://iot.xkbitcoin.com/api/dispositivos MQTT: mqtt://iot.xkbitcoin.com:1883 WebSocket: ws://iot.xkbitcoin.com:9001 Tudo está usando sua pasta /sites/xkbitcoin/video/iot/! 🚀 Precisa ajustar mais alguma coisa? eu uso apache isto nao vai quebrar meu apace Não, não vai quebrar seu Apache! Vou te mostrar como fazer de forma segura, sem afetar seus sites existentes. O segredo é criar um Virtual Host separado que não interfere nos outros. 1. Verificar sua Configuração Atual Primeiro bash # Ver sites ativos atualmente ls -la /etc/apache2/sites-enabled/ # Ver configuração atual sudo apache2ctl -S # Fazer backup de segurança (SEMPRE!) sudo cp -r /etc/apache2 /etc/apache2_backup_$(date +%Y%m%d) 2. Configuração Mais Segura - SEM mexer no que existe Vou criar um Virtual Host adicional que não afeta seus outros sites: /etc/apache2/sites-available/xkbitcoin-iot.conf: apache # Este é um NOVO Virtual Host - NÃO afeta os existentes # Usando um subdomínio diferente ServerName iot.xkbitcoin.com ServerAdmin webmaster@xkbitcoin.com # IMPORTANTE: Usando SUA pasta existente DocumentRoot /sites/xkbitcoin/video/iot/public_html # Logs SEPARADOS (não mistura com outros sites) ErrorLog /sites/xkbitcoin/video/iot/logs/error.log CustomLog /sites/xkbitcoin/video/iot/logs/access.log combined # Configurações APENAS para esta pasta Options Indexes FollowSymLinks AllowOverride All Require all granted # Proxy reverso para API (porta 3000) # Isso NÃO afeta outros Virtual Hosts ProxyPreserveHost On ProxyPass /api/ http://localhost:3000/ ProxyPassReverse /api/ http://localhost:3000/ 3. Ativar SEM Desativar Nada bash # Apenas ATIVAR o novo site (sem desativar outros) sudo a2ensite xkbitcoin-iot.conf # NÃO execute a2dissite - isso desativaria seus sites atuais! # ❌ NÃO FAÇA: sudo a2dissite 000-default.conf # ✅ Apenas adicione o novo # Verificar se a configuração está OK sudo apache2ctl configtest # Se aparecer "Syntax OK", pode recarregar sudo systemctl reload apache2 # Verificar se seus outros sites continuam funcionando curl -I http://seudominio.com # Deve responder normalmente curl -I http://iot.xkbitcoin.com # Novo site 4. Verificar se Nada Quebrou bash # Listar TODOS os Virtual Hosts ativos sudo apache2ctl -S # Você verá algo como: # *:80 é um NameVirtualHost # default server seudominio.com (/etc/apache2/sites-enabled/000-default.conf:1) # port 80 namevhost seudominio.com (/etc/apache2/sites-enabled/000-default.conf:1) # port 80 namevhost iot.xkbitcoin.com (/etc/apache2/sites-enabled/xkbitcoin-iot.conf:1) # port 80 namevhost xkbitcoin.com (/etc/apache2/sites-enabled/seu-site.conf:1) 5. Arquivo .htaccess (OPCIONAL e Seguro) Só crie se precisar, dentro da pasta do projeto: /sites/xkbitcoin/video/iot/public_html/.htaccess: apache # Isso só afeta ESTA pasta específica RewriteEngine On RewriteBase / # Não interfere em outros sites DirectoryIndex index.html 6. Teste de Isolamento bash # Teste 1: Seu site principal continua funcionando? curl -I http://xkbitcoin.com # Deve retornar 200 OK normalmente # Teste 2: O novo subdomínio funciona? curl -I http://iot.xkbitcoin.com # Deve retornar 200 OK # Teste 3: Outros sites no Apache continuam OK? # Acesse cada um no navegador para confirmar 7. Estrutura na Sua Pasta (Não Afeta Outros Arquivos) bash # Tudo fica DENTRO da sua pasta existente cd /sites/xkbitcoin/video # Criar subpasta para IoT (não mexe nos seus outros arquivos) mkdir -p iot/{public_html,api,logs} # Ver estrutura sem afetar o resto: # /sites/xkbitcoin/video/ <- Sua pasta original (intacta) # ├── [seus arquivos existentes] <- Não serão tocados # ├── iot/ <- Nova pasta (única adição) # │ ├── public_html/ # │ │ └── index.html # │ ├── api/ # │ │ └── server.js # │ └── logs/ 8. Como Reverter se Precisar bash # Se algo der errado (improvável), é fácil reverter: sudo a2dissite xkbitcoin-iot.conf sudo systemctl reload apache2 # Seu Apache volta exatamente como estava antes # Seus outros sites não foram afetados 9. Dicas de Segurança para Não Quebrar Nada bash # ✅ SEMPRE use subdomínio diferente (iot.xkbitcoin.com) # ✅ NUNCA mexa em arquivos de configuração existentes # ✅ SEMPRE faça backup antes: sudo cp -r /etc/apache2 /etc/apache2_backup_$(date +%Y%m%d_%H%M) # ✅ Teste antes de aplicar: sudo apache2ctl configtest # ✅ Use reload em vez de restart (mais seguro): sudo systemctl reload apache2 # Recarrega sem derrubar conexões # ❌ EVITE restart se tiver sites em produção: # sudo systemctl restart apache2 # Derruba todas as conexões 10. Checklist de Verificação Execute este script para verificar se está tudo bem: bash #!/bin/bash echo "🔍 Verificando Apache..." # 1. Sintaxe OK? if sudo apache2ctl configtest 2>&1 | grep -q "Syntax OK"; then echo "✅ Sintaxe da configuração OK" else echo "❌ ERRO na sintaxe!" exit 1 fi # 2. Sites ativos echo -e "\n📋 Sites ativos:" ls /etc/apache2/sites-enabled/ # 3. Portas em uso echo -e "\n🔌 Portas:" sudo netstat -tlnp | grep apache # 4. Processos echo -e "\n🟢 Processos Apache:" ps aux | grep apache | grep -v grep | wc -l echo "workers rodando" # 5. Teste local echo -e "\n🌐 Testando sites locais:" curl -s -o /dev/null -w "xkbitcoin.com: %{http_code}\n" http://localhost curl -s -o /dev/null -w "iot.xkbitcoin.com: %{http_code}\n" http://iot.xkbitcoin.com echo -e "\n✨ Verificação concluída!" Salve como check_apache.sh e execute: bash chmod +x check_apache.sh ./check_apache.sh Resumo O que NÃO vai acontecer: ❌ Seus outros sites NÃO vão cair ❌ Suas configurações existentes NÃO mudam ❌ Seus arquivos em /sites/xkbitcoin/video/ NÃO são alterados O que VAI acontecer: ✅ Um NOVO subdomínio iot.xkbitcoin.com será adicionado ✅ Uma subpasta iot/ será criada dentro da sua pasta ✅ A API Node.js rodará na porta 3000 ✅ Tudo isolado e seguro Pode ficar tranquilo! É como adicionar mais um site ao Apache, sem mexer nos existentes. Seu Apache continua funcionando normalmente com todos os outros sites. 🚀 tudo ok : Syntax OK root@vivabem:/sites/xkbitcoin/video/iot/api# sudo systemctl reload apache2 root@vivabem:/sites/xkbitcoin/video/iot/api# sudo apache2ctl -S VirtualHost configuration: 173.249.31.98:443 is a NameVirtualHost default server www.bingovip.com.br (/etc/apache2/sites-enabled/bingovip-le-ssl.conf:2) port 443 namevhost www.bingovip.com.br (/etc/apache2/sites-enabled/bingovip-le-ssl.conf:2) alias bingovip.com.br port 443 namevhost www.lotoplay.bet (/etc/apache2/sites-enabled/lotoplaybet-le-ssl.conf:2) alias lotoplay.bet port 443 namevhost www.vipsex.com.br (/etc/apache2/sites-enabled/vipsex-le-ssl.conf:2) alias vipsex.com.br port 443 namevhost www.xkbitcoin.com (/etc/apache2/sites-enabled/xkbitcoin-le-ssl.conf:2) alias xkbitcoin.com 173.249.31.98:80 is a NameVirtualHost default server www.bingovip.com.br (/etc/apache2/sites-enabled/bingovip.conf:1) port 80 namevhost www.bingovip.com.br (/etc/apache2/sites-enabled/bingovip.conf:1) alias bingovip.com.br port 80 namevhost www.lotoplay.bet (/etc/apache2/sites-enabled/lotoplaybet.conf:1) alias lotoplay.bet port 80 namevhost www.vipsex.com.br (/etc/apache2/sites-enabled/vipsex.conf:1) alias vipsex.com.br port 80 namevhost www.xkbitcoin.com (/etc/apache2/sites-enabled/xkbitcoin.conf:2) alias xkbitcoin.com *:80 iot.xkbitcoin.com (/etc/apache2/sites-enabled/xkbitcoin-iot.conf:2) ServerRoot: "/etc/apache2" Main DocumentRoot: "/var/www/html" Main ErrorLog: "/var/log/apache2/error.log" Mutex ssl-stapling: using_defaults Mutex proxy: using_defaults Mutex ssl-cache: using_defaults Mutex default: dir="/var/run/apache2/" mechanism=default Mutex mpm-accept: using_defaults Mutex watchdog-callback: using_defaults Mutex rewrite-map: using_defaults Mutex ssl-stapling-refresh: using_defaults PidFile: "/var/run/apache2/apache2.pid" Define: DUMP_VHOSTS Define: DUMP_RUN_CFG User: name="www-data" id=33 Group: name="www-data" id=33 root@vivabem:/sites/xkbitcoin/video/iot/api# Perfeito! 🎉 Tudo funcionando exatamente como deveria! Seu Apache está intacto e o novo Virtual Host do IoT foi adicionado com sucesso. Veja que no final da configuração aparece: text *:80 iot.xkbitcoin.com (/etc/apache2/sites-enabled/xkbitcoin-iot.conf:2) E todos os seus outros sites continuam normais: ✅ bingovip.com.br ✅ lotoplay.bet ✅ vipsex.com.br ✅ xkbitcoin.com Agora vamos continuar com os próximos passos: 1. Instalar Node.js e Mosquitto (se ainda não tiver) bash # Node.js curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install nodejs -y # Mosquitto MQTT sudo apt install mosquitto mosquitto-clients -y # PM2 (gerenciador de processos) sudo npm install -g pm2 2. Configurar API na sua pasta bash # Você já está em: /sites/xkbitcoin/video/iot/api # Inicializar Node.js npm init -y npm install express mqtt cors dotenv helmet 3. Criar o servidor API bash nano server.js Cole o código do server.js que te passei anteriormente (o adaptado para sua pasta). 4. Criar arquivo .env bash nano .env env PORT=3000 MQTT_USER=seu_usuario MQTT_PASS=sua_senha_segura API_TOKEN=xkbitcoin_iot_2024 NODE_ENV=production 5. Configurar Mosquitto bash # Criar usuário MQTT sudo mosquitto_passwd -c /etc/mosquitto/passwd seu_usuario # Digite a senha (anote, vai precisar no ESP32) # Configurar Mosquitto sudo nano /etc/mosquitto/conf.d/xkbitcoin.conf conf listener 1883 protocol mqtt allow_anonymous false password_file /etc/mosquitto/passwd listener 9001 protocol websockets allow_anonymous false password_file /etc/mosquitto/passwd log_dest file /sites/xkbitcoin/video/iot/logs/mosquitto.log log_type all bash sudo systemctl restart mosquitto sudo systemctl enable mosquitto 6. Criar Interface Web bash cd /sites/xkbitcoin/video/iot/public_html nano index.html Cole o código HTML do dashboard que te passei. 7. Iniciar a API bash cd /sites/xkbitcoin/video/iot/api pm2 start server.js --name xkbitcoin-iot pm2 save pm2 startup 8. Testar se está tudo online bash # Testar API localmente curl http://localhost:3000/api/health # Testar via domínio curl http://iot.xkbitcoin.com/api/health # Ver logs pm2 logs xkbitcoin-iot tail -f /sites/xkbitcoin/video/iot/logs/error.log