TKK_E32231503/backend/FIX_MQTT_MYSQL.md

451 lines
9.1 KiB
Markdown

# 🔧 Fix: Data Tidak Masuk ke MySQL Railway
## 🔍 Masalah yang Ditemukan
### 1. **Backend Tidak Connect ke HiveMQ**
- Backend menggunakan **Aedes** sebagai MQTT Broker internal
- Aedes broker **DISABLED** di Railway (tidak bisa bind port 1883)
- ESP32 publish data ke **HiveMQ** (`broker.hivemq.com`)
- Backend **TIDAK subscribe** ke HiveMQ, jadi tidak terima data dari ESP32
### 2. **Alur Data yang Salah**
```
❌ SEBELUM (TIDAK BERFUNGSI):
ESP32 → HiveMQ (broker.hivemq.com)
(data hilang)
Backend Railway (Aedes Broker) → MySQL
(tidak ada data)
```
### 3. **Solusi yang Benar**
```
✅ SESUDAH (BERFUNGSI):
ESP32 → HiveMQ (broker.hivemq.com)
Backend Railway (MQTT Client)
MySQL Database
```
---
## ✅ Perubahan yang Dilakukan
### 1. **Install MQTT Client Package**
**File: `package.json`**
```json
"dependencies": {
"mqtt": "^5.3.5", // ← TAMBAHAN BARU
...
}
```
**Install:**
```bash
cd backend
npm install mqtt
```
---
### 2. **Backend Connect ke HiveMQ sebagai Client**
**File: `server.js`**
#### Import MQTT Client:
```javascript
const mqtt = require('mqtt'); // ← TAMBAHAN BARU
```
#### Konfigurasi:
```javascript
const MQTT_BROKER_URL = process.env.MQTT_BROKER_URL || 'mqtt://broker.hivemq.com:1883';
const MQTT_TOPICS = {
data: 'novil/pengering/data',
status: 'novil/pengering/status',
button: 'novil/pengering/button',
control: 'novil/pengering/control'
};
```
#### Connect ke HiveMQ:
```javascript
const mqttClient = mqtt.connect(MQTT_BROKER_URL, {
clientId: `backend_${Math.random().toString(16).slice(2, 10)}`,
clean: true,
connectTimeout: 4000,
reconnectPeriod: 1000,
keepalive: 60
});
mqttClient.on('connect', () => {
console.log('✅ Connected to MQTT Broker (HiveMQ)');
// Subscribe to all topics
mqttClient.subscribe([
MQTT_TOPICS.data,
MQTT_TOPICS.status,
MQTT_TOPICS.button
]);
});
```
#### Handle Messages dari ESP32:
```javascript
mqttClient.on('message', async (topic, message) => {
const msg = message.toString();
// TOPIC: novil/pengering/data
if (topic === MQTT_TOPICS.data) {
const data = JSON.parse(msg);
// Update latestData
latestData = {
suhu: data.suhu || 0,
berat: data.berat || 0,
target: data.target || 0,
...
};
// Save to MySQL
await db.insertSensorData(latestData);
console.log('✅ Data saved to MySQL database');
}
// TOPIC: novil/pengering/status
if (topic === MQTT_TOPICS.status) {
// Update status
latestData.status = ...;
// Save to MySQL
await db.insertStatusHistory(msg);
console.log('✅ Status saved to MySQL database');
}
// TOPIC: novil/pengering/button
if (topic === MQTT_TOPICS.button) {
// Save button event
await db.insertStatusHistory(`BUTTON: ${msg}`);
console.log('✅ Button event saved to MySQL database');
}
});
```
#### Publish Command ke ESP32:
```javascript
app.post('/api/control', async (req, res) => {
const { command } = req.body;
// Publish to HiveMQ
mqttClient.publish(MQTT_TOPICS.control, command, { qos: 1 }, (err) => {
if (err) {
return res.status(500).json({ success: false, error: err.message });
}
console.log(`✅ Command published to MQTT: ${command}`);
res.json({ success: true, command: command });
});
});
```
---
### 3. **Update Environment Variables**
**File: `.env`**
```env
# MQTT Broker Configuration
MQTT_BROKER_URL=mqtt://broker.hivemq.com:1883
# MySQL Database Configuration (Railway)
# Isi dengan credentials dari Railway MySQL Plugin
DATABASE_URL=mysql://user:password@host:port/database
# atau:
MYSQLHOST=your-railway-mysql-host.railway.app
MYSQLPORT=3306
MYSQLUSER=root
MYSQLPASSWORD=your-password
MYSQLDATABASE=railway
```
---
## 🚀 Cara Deploy ke Railway
### 1. **Install Dependencies**
```bash
cd backend
npm install
```
### 2. **Test Lokal**
```bash
npm start
```
**Expected Output:**
```
🔄 Connecting to MQTT Broker: mqtt://broker.hivemq.com:1883
✅ Connected to MQTT Broker (HiveMQ)
✅ Subscribed to topics:
- novil/pengering/data
- novil/pengering/status
- novil/pengering/button
🚀 REST API running on port 3000
✅ Server is ready!
```
### 3. **Test dengan ESP32**
- Upload sketch ESP32
- Tekan button untuk start pengeringan
- Cek log backend:
```
📨 MQTT Message received:
Topic: novil/pengering/status
Message: PENGERINGAN DIMULAI
✅ Status saved to MySQL database
📨 MQTT Message received:
Topic: novil/pengering/data
Message: {"suhu":28.5,"berat":450,"target":315}
✅ Data saved to MySQL database
```
### 4. **Push ke GitHub**
```bash
git add .
git commit -m "Fix: Backend connect to HiveMQ as MQTT client"
git push
```
### 5. **Configure Railway Environment Variables**
Di Railway Dashboard:
1. Buka project → Variables
2. Tambahkan:
- `MQTT_BROKER_URL` = `mqtt://broker.hivemq.com:1883`
3. MySQL credentials sudah otomatis dari Railway MySQL Plugin:
- `MYSQLHOST`
- `MYSQLPORT`
- `MYSQLUSER`
- `MYSQLPASSWORD`
- `MYSQLDATABASE`
### 6. **Redeploy**
Railway akan auto-deploy setelah push ke GitHub.
---
## 🧪 Testing
### 1. **Test MQTT Connection**
```bash
curl https://your-app.railway.app/api/stats
```
**Expected Response:**
```json
{
"success": true,
"stats": {
"mqttConnected": true, // ← Harus true
"sensorDataCount": 123,
"statusHistoryCount": 45,
...
}
}
```
### 2. **Test Data dari ESP32**
- Jalankan ESP32
- Tunggu beberapa detik
- Check database:
```bash
curl https://your-app.railway.app/api/data/latest
```
**Expected Response:**
```json
{
"success": true,
"data": {
"suhu": 28.5,
"berat": 450.0,
"target": 315.0,
"status": "RUNNING",
"timestamp": "2026-05-28T10:30:00.000Z"
}
}
```
### 3. **Test History**
```bash
curl https://your-app.railway.app/api/data/history?limit=10
```
**Expected Response:**
```json
{
"success": true,
"count": 10,
"data": [
{
"id": 1,
"suhu": 28.5,
"berat": 450.0,
"target": 315.0,
"timestamp": "2026-05-28 10:30:00"
},
...
]
}
```
### 4. **Test Send Command**
```bash
curl -X POST https://your-app.railway.app/api/control \
-H "Content-Type: application/json" \
-d '{"command":"HEATER_ON"}'
```
**Expected Response:**
```json
{
"success": true,
"message": "Command sent successfully",
"command": "HEATER_ON"
}
```
**Check ESP32 Serial Monitor:**
```
MQTT Message [novil/pengering/control] : HEATER_ON
HEATER ON
```
---
## 📊 Monitoring
### Railway Logs
```bash
# Di Railway Dashboard → Deployments → View Logs
```
**Expected Logs:**
```
✅ Connected to MQTT Broker (HiveMQ)
✅ Subscribed to topics
📨 MQTT Message received: novil/pengering/data
✅ Data saved to MySQL database
📨 MQTT Message received: novil/pengering/status
✅ Status saved to MySQL database
```
### ESP32 Serial Monitor
```
MQTT Data Sent: {"suhu":28.5,"berat":450,"target":315}
MQTT Data Sent: {"suhu":28.6,"berat":448,"target":315}
```
---
## 🔍 Troubleshooting
### Problem: `mqttConnected: false`
**Cause:** Backend tidak bisa connect ke HiveMQ
**Solution:**
1. Check Railway logs untuk error
2. Pastikan `MQTT_BROKER_URL` benar
3. Check firewall/network Railway
---
### Problem: Data masih tidak masuk ke MySQL
**Cause:** Database credentials salah
**Solution:**
1. Check Railway MySQL Plugin variables
2. Pastikan `MYSQLHOST`, `MYSQLUSER`, `MYSQLPASSWORD`, `MYSQLDATABASE` benar
3. Test connection:
```bash
curl https://your-app.railway.app/api/database/test
```
---
### Problem: ESP32 tidak terima command
**Cause:** ESP32 tidak subscribe ke topic control
**Solution:**
1. Check ESP32 Serial Monitor:
```
Subscribed to: novil/pengering/control
```
2. Restart ESP32
3. Check MQTT connection
---
## 📝 Ringkasan Perubahan
| Aspek | Sebelum | Sesudah |
|-------|---------|---------|
| MQTT Role | ❌ Broker (Aedes) | ✅ Client (mqtt.js) |
| Connect to HiveMQ | ❌ Tidak | ✅ Ya |
| Subscribe Topics | ❌ Tidak | ✅ Ya (data, status, button) |
| Publish Commands | ⚠️ Via Aedes | ✅ Via HiveMQ |
| Save to MySQL | ❌ Tidak ada data | ✅ Berfungsi |
| Package | Aedes only | ✅ Aedes + mqtt |
---
## ✅ Checklist
### Pre-Deploy:
- [x] Install package `mqtt`
- [x] Update `server.js` dengan MQTT client
- [x] Update `.env` dengan MQTT_BROKER_URL
- [x] Test lokal
### Deploy:
- [ ] Push ke GitHub
- [ ] Configure Railway environment variables
- [ ] Wait for auto-deploy
- [ ] Check Railway logs
### Post-Deploy:
- [ ] Test `/api/stats``mqttConnected: true`
- [ ] Test ESP32 → data masuk ke MySQL
- [ ] Test `/api/data/latest` → ada data
- [ ] Test `/api/data/history` → ada history
- [ ] Test send command → ESP32 terima
---
## 🎯 Expected Result
Setelah fix ini:
1. ✅ Backend connect ke HiveMQ sebagai MQTT client
2. ✅ Backend subscribe ke topic `novil/pengering/data`, `status`, `button`
3. ✅ ESP32 publish data → Backend terima → Save ke MySQL
4. ✅ Flutter send command → Backend publish ke HiveMQ → ESP32 terima
5. ✅ Data history tersimpan di MySQL Railway
6. ✅ Status history tersimpan di MySQL Railway
---
Selamat mencoba! 🚀🎉