Fix: Subscribe to control topic and save to database
This commit is contained in:
parent
59d89ae7a5
commit
ce1b178ae5
|
|
@ -0,0 +1,319 @@
|
||||||
|
# Deploy Perbaikan Control Commands ke Railway
|
||||||
|
|
||||||
|
## Perubahan yang Dilakukan
|
||||||
|
✅ Backend sekarang **subscribe ke topic `novil/pengering/control`**
|
||||||
|
✅ Handler untuk menyimpan pesan control ke database `control_commands`
|
||||||
|
✅ Handler untuk update status relay dari ESP32
|
||||||
|
|
||||||
|
## Cara Deploy ke Railway
|
||||||
|
|
||||||
|
### Opsi 1: Deploy via Git (Recommended)
|
||||||
|
|
||||||
|
#### 1. Commit Perubahan
|
||||||
|
```bash
|
||||||
|
cd c:\Users\abilh\aplikasi_novil
|
||||||
|
|
||||||
|
# Cek status
|
||||||
|
git status
|
||||||
|
|
||||||
|
# Add file yang berubah
|
||||||
|
git add backend/server.js
|
||||||
|
git add PERBAIKAN_CONTROL_COMMANDS.md
|
||||||
|
git add backend/DEPLOY_PERBAIKAN.md
|
||||||
|
|
||||||
|
# Commit
|
||||||
|
git commit -m "Fix: Subscribe to control topic and save to database"
|
||||||
|
|
||||||
|
# Push ke repository
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Railway Auto-Deploy
|
||||||
|
- Railway akan otomatis detect perubahan
|
||||||
|
- Build dan deploy akan berjalan otomatis
|
||||||
|
- Tunggu hingga status "Deployed" (biasanya 2-3 menit)
|
||||||
|
|
||||||
|
#### 3. Verifikasi Deployment
|
||||||
|
```bash
|
||||||
|
# Cek health check
|
||||||
|
curl https://your-railway-app.up.railway.app/
|
||||||
|
|
||||||
|
# Cek stats
|
||||||
|
curl https://your-railway-app.up.railway.app/api/stats
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Opsi 2: Deploy via Railway CLI
|
||||||
|
|
||||||
|
#### 1. Install Railway CLI (jika belum)
|
||||||
|
```bash
|
||||||
|
# Windows (PowerShell)
|
||||||
|
iwr https://railway.app/install.ps1 | iex
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Login ke Railway
|
||||||
|
```bash
|
||||||
|
railway login
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Link Project
|
||||||
|
```bash
|
||||||
|
cd c:\Users\abilh\aplikasi_novil\backend
|
||||||
|
railway link
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Deploy
|
||||||
|
```bash
|
||||||
|
railway up
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. Cek Logs
|
||||||
|
```bash
|
||||||
|
railway logs
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Opsi 3: Manual Upload via Railway Dashboard
|
||||||
|
|
||||||
|
#### 1. Buka Railway Dashboard
|
||||||
|
- Login ke https://railway.app
|
||||||
|
- Pilih project "aplikasi_novil" atau nama project Anda
|
||||||
|
|
||||||
|
#### 2. Buka Service Backend
|
||||||
|
- Klik service backend Anda
|
||||||
|
- Pilih tab "Deployments"
|
||||||
|
|
||||||
|
#### 3. Trigger Redeploy
|
||||||
|
- Klik tombol "Deploy" atau "Redeploy"
|
||||||
|
- Pilih branch yang benar (main/master)
|
||||||
|
- Railway akan pull code terbaru dan deploy
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verifikasi Setelah Deploy
|
||||||
|
|
||||||
|
### 1. Cek Logs Railway
|
||||||
|
|
||||||
|
Di Railway Dashboard → Service → Logs, pastikan muncul:
|
||||||
|
|
||||||
|
```
|
||||||
|
✅ Subscribed to topics:
|
||||||
|
- novil/pengering/data
|
||||||
|
- novil/pengering/status
|
||||||
|
- novil/pengering/button
|
||||||
|
- novil/pengering/control ← HARUS ADA INI
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Test API Health Check
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ganti dengan URL Railway Anda
|
||||||
|
curl https://your-app.up.railway.app/
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "OK",
|
||||||
|
"message": "Pengering Ikan Backend Server - MQTT Client Enabled",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"uptime": 123.45,
|
||||||
|
"timestamp": "2026-05-29T10:30:00.000Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Test Stats API
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl https://your-app.up.railway.app/api/stats
|
||||||
|
```
|
||||||
|
|
||||||
|
Response harus include:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"stats": {
|
||||||
|
"mqttConnected": true,
|
||||||
|
"sensorDataCount": 100,
|
||||||
|
"statusHistoryCount": 50,
|
||||||
|
"controlCommandsCount": 10, ← HARUS ADA INI
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Test Control Command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Kirim command test
|
||||||
|
curl -X POST https://your-app.up.railway.app/api/control \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"command":"HEATER_ON"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "Command sent successfully",
|
||||||
|
"command": "HEATER_ON"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. Cek Database Railway
|
||||||
|
|
||||||
|
Login ke Railway MySQL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via Railway CLI
|
||||||
|
railway connect MySQL
|
||||||
|
```
|
||||||
|
|
||||||
|
Atau via Railway Dashboard → MySQL → Connect → Copy connection string
|
||||||
|
|
||||||
|
Query untuk verifikasi:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Cek apakah ada data di control_commands
|
||||||
|
SELECT COUNT(*) as total FROM control_commands;
|
||||||
|
|
||||||
|
-- Lihat 10 command terakhir
|
||||||
|
SELECT * FROM control_commands ORDER BY timestamp DESC LIMIT 10;
|
||||||
|
|
||||||
|
-- Lihat status relay terakhir
|
||||||
|
SELECT * FROM status_history
|
||||||
|
WHERE message LIKE 'RELAY:%'
|
||||||
|
ORDER BY timestamp DESC LIMIT 10;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing dengan ESP32
|
||||||
|
|
||||||
|
### 1. Update Kode ESP32 (jika perlu)
|
||||||
|
|
||||||
|
Pastikan ESP32 menggunakan URL Railway yang benar:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Di file esp32_pengering_ikan_railway.ino
|
||||||
|
const char* mqtt_server = "broker.hivemq.com";
|
||||||
|
const int mqtt_port = 1883;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Upload ke ESP32
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Via Arduino IDE atau PlatformIO
|
||||||
|
# Upload esp32_pengering_ikan_v2.ino
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Monitor Serial ESP32
|
||||||
|
|
||||||
|
Buka Serial Monitor (115200 baud), pastikan muncul:
|
||||||
|
|
||||||
|
```
|
||||||
|
WiFi Connected
|
||||||
|
MQTT Connected
|
||||||
|
Heater → ON
|
||||||
|
Fan → ON
|
||||||
|
Data sent: {"suhu":28.5,"berat":450,...}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Cek Railway Logs Real-time
|
||||||
|
|
||||||
|
Di Railway Dashboard → Logs, pastikan muncul:
|
||||||
|
|
||||||
|
```
|
||||||
|
📨 MQTT Message received:
|
||||||
|
Topic: novil/pengering/control
|
||||||
|
Message: STATUS:HEATER_ON
|
||||||
|
🎛️ Control Message: STATUS:HEATER_ON
|
||||||
|
📊 Relay Status Update: HEATER_ON
|
||||||
|
✅ Relay status saved to MySQL database
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### ❌ Logs tidak muncul "Subscribed to control topic"
|
||||||
|
|
||||||
|
**Solusi:**
|
||||||
|
1. Pastikan file `server.js` sudah ter-commit dan ter-push
|
||||||
|
2. Trigger manual redeploy di Railway Dashboard
|
||||||
|
3. Cek Railway logs untuk error
|
||||||
|
|
||||||
|
### ❌ Database connection failed
|
||||||
|
|
||||||
|
**Solusi:**
|
||||||
|
1. Cek environment variables di Railway Dashboard
|
||||||
|
2. Pastikan MySQL plugin sudah ter-install
|
||||||
|
3. Verifikasi `DATABASE_URL` atau `MYSQL*` variables ada
|
||||||
|
|
||||||
|
### ❌ MQTT not connected
|
||||||
|
|
||||||
|
**Solusi:**
|
||||||
|
1. Cek `MQTT_BROKER_URL` di Railway environment variables
|
||||||
|
2. Default: `mqtt://broker.hivemq.com:1883`
|
||||||
|
3. Pastikan Railway tidak block port 1883
|
||||||
|
|
||||||
|
### ❌ Control commands tidak masuk database
|
||||||
|
|
||||||
|
**Solusi:**
|
||||||
|
1. Cek Railway logs: `railway logs`
|
||||||
|
2. Pastikan ESP32 kirim ke topic yang benar: `novil/pengering/control`
|
||||||
|
3. Verifikasi database table `control_commands` sudah ada:
|
||||||
|
```sql
|
||||||
|
SHOW TABLES;
|
||||||
|
DESCRIBE control_commands;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist Deployment
|
||||||
|
|
||||||
|
- [ ] Commit perubahan `server.js`
|
||||||
|
- [ ] Push ke Git repository
|
||||||
|
- [ ] Railway auto-deploy selesai (status: Deployed)
|
||||||
|
- [ ] Cek logs: "Subscribed to control topic" muncul
|
||||||
|
- [ ] Test API health check berhasil
|
||||||
|
- [ ] Test API stats menunjukkan `controlCommandsCount`
|
||||||
|
- [ ] Test kirim command via API berhasil
|
||||||
|
- [ ] Database table `control_commands` ada data
|
||||||
|
- [ ] ESP32 connect ke MQTT berhasil
|
||||||
|
- [ ] ESP32 kirim status relay, muncul di Railway logs
|
||||||
|
- [ ] Database `control_commands` bertambah saat ESP32 kirim status
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## URL Penting
|
||||||
|
|
||||||
|
Ganti dengan URL Railway Anda:
|
||||||
|
|
||||||
|
- **Backend API:** `https://your-app.up.railway.app`
|
||||||
|
- **Health Check:** `https://your-app.up.railway.app/`
|
||||||
|
- **Stats:** `https://your-app.up.railway.app/api/stats`
|
||||||
|
- **Control:** `https://your-app.up.railway.app/api/control`
|
||||||
|
- **Data History:** `https://your-app.up.railway.app/api/data/history`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Setelah Deploy Berhasil
|
||||||
|
|
||||||
|
1. ✅ Update dokumentasi dengan URL Railway yang benar
|
||||||
|
2. ✅ Test dengan Flutter app (jika ada)
|
||||||
|
3. ✅ Monitor logs Railway untuk memastikan tidak ada error
|
||||||
|
4. ✅ Setup monitoring/alerting (optional)
|
||||||
|
5. ✅ Backup database secara berkala
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kontak & Support
|
||||||
|
|
||||||
|
Jika ada masalah:
|
||||||
|
1. Cek Railway logs: `railway logs`
|
||||||
|
2. Cek Railway Dashboard → Service → Logs
|
||||||
|
3. Cek Railway Dashboard → MySQL → Metrics
|
||||||
|
4. Review dokumentasi: `PERBAIKAN_CONTROL_COMMANDS.md`
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
# =====================================================
|
||||||
|
# Script Deploy Backend ke Railway
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " DEPLOY BACKEND KE RAILWAY" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Cek apakah di folder yang benar
|
||||||
|
$currentPath = Get-Location
|
||||||
|
if (-not $currentPath.Path.EndsWith("backend")) {
|
||||||
|
Write-Host "❌ Error: Script harus dijalankan dari folder backend" -ForegroundColor Red
|
||||||
|
Write-Host " Current path: $currentPath" -ForegroundColor Yellow
|
||||||
|
Write-Host " Pindah ke folder backend dulu:" -ForegroundColor Yellow
|
||||||
|
Write-Host " cd backend" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "📁 Current directory: $currentPath" -ForegroundColor Green
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 1. CEK GIT STATUS
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "🔍 Checking Git status..." -ForegroundColor Yellow
|
||||||
|
git status --short
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
$confirm = Read-Host "Lanjutkan commit dan push? (y/n)"
|
||||||
|
if ($confirm -ne "y") {
|
||||||
|
Write-Host "❌ Deployment dibatalkan" -ForegroundColor Red
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 2. GIT ADD
|
||||||
|
# =====================================================
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "📦 Adding files to Git..." -ForegroundColor Yellow
|
||||||
|
git add server.js
|
||||||
|
git add DEPLOY_PERBAIKAN.md
|
||||||
|
git add deploy-to-railway.ps1
|
||||||
|
git add ../PERBAIKAN_CONTROL_COMMANDS.md
|
||||||
|
|
||||||
|
Write-Host "✅ Files added" -ForegroundColor Green
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 3. GIT COMMIT
|
||||||
|
# =====================================================
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "💾 Committing changes..." -ForegroundColor Yellow
|
||||||
|
$commitMessage = "Fix: Subscribe to control topic and save to database
|
||||||
|
|
||||||
|
- Backend now subscribes to novil/pengering/control topic
|
||||||
|
- Added handler to save control commands to database
|
||||||
|
- Added handler to update relay status from ESP32
|
||||||
|
- Status messages with STATUS: prefix saved to status_history
|
||||||
|
- Command messages saved to control_commands table"
|
||||||
|
|
||||||
|
git commit -m $commitMessage
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "✅ Commit successful" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "⚠️ No changes to commit or commit failed" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 4. GIT PUSH
|
||||||
|
# =====================================================
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "🚀 Pushing to repository..." -ForegroundColor Yellow
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "✅ Push successful" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "❌ Push failed" -ForegroundColor Red
|
||||||
|
Write-Host " Coba push manual: git push origin main" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 5. TUNGGU RAILWAY DEPLOY
|
||||||
|
# =====================================================
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "⏳ Railway sedang deploy..." -ForegroundColor Yellow
|
||||||
|
Write-Host " Buka Railway Dashboard untuk monitor progress:" -ForegroundColor Cyan
|
||||||
|
Write-Host " https://railway.app/dashboard" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host " Tunggu hingga status: ✅ Deployed" -ForegroundColor Green
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
$waitDeploy = Read-Host "Sudah selesai deploy? (y/n)"
|
||||||
|
if ($waitDeploy -ne "y") {
|
||||||
|
Write-Host "⏸️ Tunggu deploy selesai dulu, lalu jalankan test manual" -ForegroundColor Yellow
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 6. TEST DEPLOYMENT
|
||||||
|
# =====================================================
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "🧪 Testing deployment..." -ForegroundColor Yellow
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
$railwayUrl = Read-Host "Masukkan URL Railway (contoh: https://your-app.up.railway.app)"
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($railwayUrl)) {
|
||||||
|
Write-Host "⚠️ URL tidak diisi, skip testing" -ForegroundColor Yellow
|
||||||
|
Write-Host " Test manual dengan:" -ForegroundColor Yellow
|
||||||
|
Write-Host " curl https://your-app.up.railway.app/" -ForegroundColor Cyan
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove trailing slash
|
||||||
|
$railwayUrl = $railwayUrl.TrimEnd('/')
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "📡 Testing health check..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$response = Invoke-RestMethod -Uri "$railwayUrl/" -Method Get
|
||||||
|
Write-Host "✅ Health check OK" -ForegroundColor Green
|
||||||
|
Write-Host " Status: $($response.status)" -ForegroundColor Cyan
|
||||||
|
Write-Host " Message: $($response.message)" -ForegroundColor Cyan
|
||||||
|
Write-Host " Version: $($response.version)" -ForegroundColor Cyan
|
||||||
|
} catch {
|
||||||
|
Write-Host "❌ Health check failed" -ForegroundColor Red
|
||||||
|
Write-Host " Error: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "📊 Testing stats..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$response = Invoke-RestMethod -Uri "$railwayUrl/api/stats" -Method Get
|
||||||
|
Write-Host "✅ Stats OK" -ForegroundColor Green
|
||||||
|
Write-Host " MQTT Connected: $($response.stats.mqttConnected)" -ForegroundColor Cyan
|
||||||
|
Write-Host " Sensor Data Count: $($response.stats.sensorDataCount)" -ForegroundColor Cyan
|
||||||
|
Write-Host " Status History Count: $($response.stats.statusHistoryCount)" -ForegroundColor Cyan
|
||||||
|
Write-Host " Control Commands Count: $($response.stats.controlCommandsCount)" -ForegroundColor Cyan
|
||||||
|
} catch {
|
||||||
|
Write-Host "❌ Stats failed" -ForegroundColor Red
|
||||||
|
Write-Host " Error: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "🎛️ Testing control command..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$body = @{
|
||||||
|
command = "HEATER_ON"
|
||||||
|
} | ConvertTo-Json
|
||||||
|
|
||||||
|
$response = Invoke-RestMethod -Uri "$railwayUrl/api/control" -Method Post -Body $body -ContentType "application/json"
|
||||||
|
Write-Host "✅ Control command OK" -ForegroundColor Green
|
||||||
|
Write-Host " Success: $($response.success)" -ForegroundColor Cyan
|
||||||
|
Write-Host " Message: $($response.message)" -ForegroundColor Cyan
|
||||||
|
Write-Host " Command: $($response.command)" -ForegroundColor Cyan
|
||||||
|
} catch {
|
||||||
|
Write-Host "❌ Control command failed" -ForegroundColor Red
|
||||||
|
Write-Host " Error: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 7. SELESAI
|
||||||
|
# =====================================================
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " ✅ DEPLOYMENT SELESAI" -ForegroundColor Green
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "📋 Next Steps:" -ForegroundColor Yellow
|
||||||
|
Write-Host " 1. Cek Railway logs untuk memastikan subscribe ke control topic" -ForegroundColor White
|
||||||
|
Write-Host " 2. Upload kode ESP32 (esp32_pengering_ikan_v2.ino)" -ForegroundColor White
|
||||||
|
Write-Host " 3. Monitor Serial ESP32 untuk melihat status relay" -ForegroundColor White
|
||||||
|
Write-Host " 4. Cek database Railway untuk memastikan data masuk" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "📚 Dokumentasi:" -ForegroundColor Yellow
|
||||||
|
Write-Host " - PERBAIKAN_CONTROL_COMMANDS.md" -ForegroundColor Cyan
|
||||||
|
Write-Host " - DEPLOY_PERBAIKAN.md" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "🔗 Railway URL: $railwayUrl" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
|
@ -107,7 +107,8 @@ mqttClient.on('connect', () => {
|
||||||
mqttClient.subscribe([
|
mqttClient.subscribe([
|
||||||
MQTT_TOPICS.data,
|
MQTT_TOPICS.data,
|
||||||
MQTT_TOPICS.status,
|
MQTT_TOPICS.status,
|
||||||
MQTT_TOPICS.button
|
MQTT_TOPICS.button,
|
||||||
|
MQTT_TOPICS.control
|
||||||
], (err) => {
|
], (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('❌ Failed to subscribe:', err);
|
console.error('❌ Failed to subscribe:', err);
|
||||||
|
|
@ -116,6 +117,7 @@ mqttClient.on('connect', () => {
|
||||||
console.log(' -', MQTT_TOPICS.data);
|
console.log(' -', MQTT_TOPICS.data);
|
||||||
console.log(' -', MQTT_TOPICS.status);
|
console.log(' -', MQTT_TOPICS.status);
|
||||||
console.log(' -', MQTT_TOPICS.button);
|
console.log(' -', MQTT_TOPICS.button);
|
||||||
|
console.log(' -', MQTT_TOPICS.control);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -224,6 +226,44 @@ mqttClient.on('message', async (topic, message) => {
|
||||||
console.error('❌ Failed to save button event:', dbError.message);
|
console.error('❌ Failed to save button event:', dbError.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// TOPIC: novil/pengering/control
|
||||||
|
// Format: "STATUS:HEATER_ON", "HEATER_ON", "FAN_OFF", dll
|
||||||
|
// =====================================================
|
||||||
|
if (topic === MQTT_TOPICS.control) {
|
||||||
|
console.log('🎛️ Control Message:', msg);
|
||||||
|
|
||||||
|
// Jika pesan dimulai dengan "STATUS:", ini adalah feedback dari ESP32
|
||||||
|
if (msg.startsWith('STATUS:')) {
|
||||||
|
const statusMsg = msg.replace('STATUS:', '');
|
||||||
|
console.log('📊 Relay Status Update:', statusMsg);
|
||||||
|
|
||||||
|
// Update relay state di latestData
|
||||||
|
if (statusMsg === 'HEATER_ON') latestData.relay1 = true;
|
||||||
|
else if (statusMsg === 'HEATER_OFF') latestData.relay1 = false;
|
||||||
|
else if (statusMsg === 'FAN_ON') latestData.relay2 = true;
|
||||||
|
else if (statusMsg === 'FAN_OFF') latestData.relay2 = false;
|
||||||
|
else if (statusMsg === 'EXHAUST_ON') latestData.relay3 = true;
|
||||||
|
else if (statusMsg === 'EXHAUST_OFF') latestData.relay3 = false;
|
||||||
|
|
||||||
|
// Save status update to status_history
|
||||||
|
try {
|
||||||
|
await db.insertStatusHistory(`RELAY: ${statusMsg}`);
|
||||||
|
console.log('✅ Relay status saved to MySQL database');
|
||||||
|
} catch (dbError) {
|
||||||
|
console.error('❌ Failed to save relay status:', dbError.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Ini adalah command dari API/Flutter, simpan ke control_commands
|
||||||
|
try {
|
||||||
|
await db.insertControlCommand(msg, 'MQTT');
|
||||||
|
console.log('✅ Control command saved to MySQL database');
|
||||||
|
} catch (dbError) {
|
||||||
|
console.error('❌ Failed to save control command:', dbError.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
@ -330,6 +370,44 @@ aedes.on('publish', async (packet, client) => {
|
||||||
console.error('❌ Failed to save button event:', dbError.message);
|
console.error('❌ Failed to save button event:', dbError.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// TOPIC: novil/pengering/control
|
||||||
|
// Format: "STATUS:HEATER_ON", "HEATER_ON", "FAN_OFF", dll
|
||||||
|
// =====================================================
|
||||||
|
if (topic === 'novil/pengering/control') {
|
||||||
|
console.log('🎛️ Control Message:', message);
|
||||||
|
|
||||||
|
// Jika pesan dimulai dengan "STATUS:", ini adalah feedback dari ESP32
|
||||||
|
if (message.startsWith('STATUS:')) {
|
||||||
|
const statusMsg = message.replace('STATUS:', '');
|
||||||
|
console.log('📊 Relay Status Update:', statusMsg);
|
||||||
|
|
||||||
|
// Update relay state di latestData
|
||||||
|
if (statusMsg === 'HEATER_ON') latestData.relay1 = true;
|
||||||
|
else if (statusMsg === 'HEATER_OFF') latestData.relay1 = false;
|
||||||
|
else if (statusMsg === 'FAN_ON') latestData.relay2 = true;
|
||||||
|
else if (statusMsg === 'FAN_OFF') latestData.relay2 = false;
|
||||||
|
else if (statusMsg === 'EXHAUST_ON') latestData.relay3 = true;
|
||||||
|
else if (statusMsg === 'EXHAUST_OFF') latestData.relay3 = false;
|
||||||
|
|
||||||
|
// Save status update to status_history
|
||||||
|
try {
|
||||||
|
await db.insertStatusHistory(`RELAY: ${statusMsg}`);
|
||||||
|
console.log('✅ Relay status saved to database');
|
||||||
|
} catch (dbError) {
|
||||||
|
console.error('❌ Failed to save relay status:', dbError.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Ini adalah command dari API/Flutter, simpan ke control_commands
|
||||||
|
try {
|
||||||
|
await db.insertControlCommand(message, 'MQTT');
|
||||||
|
console.log('✅ Control command saved to database');
|
||||||
|
} catch (dbError) {
|
||||||
|
console.error('❌ Failed to save control command:', dbError.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,206 @@
|
||||||
|
# =====================================================
|
||||||
|
# Script Test Control Topic di Railway
|
||||||
|
# =====================================================
|
||||||
|
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$false)]
|
||||||
|
[string]$RailwayUrl = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " TEST CONTROL TOPIC" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# Minta URL jika tidak diberikan
|
||||||
|
if ([string]::IsNullOrWhiteSpace($RailwayUrl)) {
|
||||||
|
$RailwayUrl = Read-Host "Masukkan URL Railway (contoh: https://your-app.up.railway.app)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove trailing slash
|
||||||
|
$RailwayUrl = $RailwayUrl.TrimEnd('/')
|
||||||
|
|
||||||
|
Write-Host "🔗 Railway URL: $RailwayUrl" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 1. HEALTH CHECK
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "1️⃣ Testing Health Check..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$response = Invoke-RestMethod -Uri "$RailwayUrl/" -Method Get
|
||||||
|
Write-Host " ✅ Status: $($response.status)" -ForegroundColor Green
|
||||||
|
Write-Host " 📦 Version: $($response.version)" -ForegroundColor Cyan
|
||||||
|
Write-Host " ⏱️ Uptime: $([math]::Round($response.uptime, 2))s" -ForegroundColor Cyan
|
||||||
|
} catch {
|
||||||
|
Write-Host " ❌ Failed: $_" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 2. STATS CHECK
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "2️⃣ Testing Stats API..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$response = Invoke-RestMethod -Uri "$RailwayUrl/api/stats" -Method Get
|
||||||
|
Write-Host " ✅ Stats retrieved successfully" -ForegroundColor Green
|
||||||
|
Write-Host " 🔌 MQTT Connected: $($response.stats.mqttConnected)" -ForegroundColor Cyan
|
||||||
|
Write-Host " 📊 Sensor Data: $($response.stats.sensorDataCount)" -ForegroundColor Cyan
|
||||||
|
Write-Host " 📝 Status History: $($response.stats.statusHistoryCount)" -ForegroundColor Cyan
|
||||||
|
Write-Host " 🎛️ Control Commands: $($response.stats.controlCommandsCount)" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
if ($response.stats.controlCommandsCount -eq $null) {
|
||||||
|
Write-Host " ⚠️ WARNING: controlCommandsCount is null!" -ForegroundColor Yellow
|
||||||
|
Write-Host " Kemungkinan table control_commands belum ada atau kosong" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " ❌ Failed: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 3. TEST CONTROL COMMANDS
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "3️⃣ Testing Control Commands..." -ForegroundColor Yellow
|
||||||
|
|
||||||
|
$commands = @("HEATER_ON", "FAN_ON", "EXHAUST_ON", "HEATER_OFF", "FAN_OFF", "EXHAUST_OFF")
|
||||||
|
|
||||||
|
foreach ($cmd in $commands) {
|
||||||
|
Write-Host " 📤 Sending: $cmd" -ForegroundColor Cyan
|
||||||
|
try {
|
||||||
|
$body = @{
|
||||||
|
command = $cmd
|
||||||
|
} | ConvertTo-Json
|
||||||
|
|
||||||
|
$response = Invoke-RestMethod -Uri "$RailwayUrl/api/control" -Method Post -Body $body -ContentType "application/json"
|
||||||
|
|
||||||
|
if ($response.success) {
|
||||||
|
Write-Host " ✅ Success" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " ❌ Failed: $($response.message)" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " ❌ Error: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
Start-Sleep -Milliseconds 500
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 4. CHECK STATS AGAIN
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "4️⃣ Checking Stats After Commands..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$response = Invoke-RestMethod -Uri "$RailwayUrl/api/stats" -Method Get
|
||||||
|
Write-Host " ✅ Stats retrieved" -ForegroundColor Green
|
||||||
|
Write-Host " 🎛️ Control Commands Count: $($response.stats.controlCommandsCount)" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
if ($response.stats.controlCommandsCount -gt 0) {
|
||||||
|
Write-Host " ✅ Control commands berhasil tersimpan!" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " ⚠️ Control commands masih 0" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " ❌ Failed: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 5. TEST INVALID COMMAND
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "5️⃣ Testing Invalid Command..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$body = @{
|
||||||
|
command = "INVALID_COMMAND"
|
||||||
|
} | ConvertTo-Json
|
||||||
|
|
||||||
|
$response = Invoke-RestMethod -Uri "$RailwayUrl/api/control" -Method Post -Body $body -ContentType "application/json"
|
||||||
|
Write-Host " ⚠️ Invalid command accepted (should be rejected)" -ForegroundColor Yellow
|
||||||
|
} catch {
|
||||||
|
$errorResponse = $_.ErrorDetails.Message | ConvertFrom-Json
|
||||||
|
if ($errorResponse.message -like "*Invalid command*") {
|
||||||
|
Write-Host " ✅ Invalid command correctly rejected" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host " ❌ Unexpected error: $($errorResponse.message)" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 6. GET DATA HISTORY
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "6️⃣ Getting Data History..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$response = Invoke-RestMethod -Uri "$RailwayUrl/api/data/history?limit=5" -Method Get
|
||||||
|
Write-Host " ✅ Retrieved $($response.count) records" -ForegroundColor Green
|
||||||
|
|
||||||
|
if ($response.count -gt 0) {
|
||||||
|
$latest = $response.data[0]
|
||||||
|
Write-Host " 📊 Latest Data:" -ForegroundColor Cyan
|
||||||
|
Write-Host " Suhu: $($latest.suhu)°C" -ForegroundColor White
|
||||||
|
Write-Host " Berat: $($latest.berat)g" -ForegroundColor White
|
||||||
|
Write-Host " Relay1 (Heater): $($latest.relay1)" -ForegroundColor White
|
||||||
|
Write-Host " Relay2 (Fan): $($latest.relay2)" -ForegroundColor White
|
||||||
|
Write-Host " Relay3 (Exhaust): $($latest.relay3)" -ForegroundColor White
|
||||||
|
Write-Host " Status: $($latest.status)" -ForegroundColor White
|
||||||
|
Write-Host " Timestamp: $($latest.timestamp)" -ForegroundColor White
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " ❌ Failed: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# 7. GET STATUS HISTORY
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "7️⃣ Getting Status History..." -ForegroundColor Yellow
|
||||||
|
try {
|
||||||
|
$response = Invoke-RestMethod -Uri "$RailwayUrl/api/status/history?limit=10" -Method Get
|
||||||
|
Write-Host " ✅ Retrieved $($response.count) records" -ForegroundColor Green
|
||||||
|
|
||||||
|
if ($response.count -gt 0) {
|
||||||
|
Write-Host " 📝 Recent Status Messages:" -ForegroundColor Cyan
|
||||||
|
foreach ($status in $response.data | Select-Object -First 5) {
|
||||||
|
Write-Host " - $($status.message)" -ForegroundColor White
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Write-Host " ❌ Failed: $_" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# =====================================================
|
||||||
|
# SUMMARY
|
||||||
|
# =====================================================
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host " 📋 TEST SUMMARY" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "✅ Checklist:" -ForegroundColor Yellow
|
||||||
|
Write-Host " [ ] Health check berhasil" -ForegroundColor White
|
||||||
|
Write-Host " [ ] Stats API menampilkan controlCommandsCount" -ForegroundColor White
|
||||||
|
Write-Host " [ ] Control commands berhasil dikirim" -ForegroundColor White
|
||||||
|
Write-Host " [ ] Control commands tersimpan di database" -ForegroundColor White
|
||||||
|
Write-Host " [ ] Invalid command ditolak" -ForegroundColor White
|
||||||
|
Write-Host " [ ] Data history dapat diambil" -ForegroundColor White
|
||||||
|
Write-Host " [ ] Status history dapat diambil" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "📚 Next Steps:" -ForegroundColor Yellow
|
||||||
|
Write-Host " 1. Cek Railway logs untuk melihat MQTT messages" -ForegroundColor White
|
||||||
|
Write-Host " 2. Upload ESP32 code dan test dengan hardware" -ForegroundColor White
|
||||||
|
Write-Host " 3. Monitor database Railway untuk memastikan data masuk" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "🔗 Useful URLs:" -ForegroundColor Yellow
|
||||||
|
Write-Host " Health: $RailwayUrl/" -ForegroundColor Cyan
|
||||||
|
Write-Host " Stats: $RailwayUrl/api/stats" -ForegroundColor Cyan
|
||||||
|
Write-Host " Control: $RailwayUrl/api/control" -ForegroundColor Cyan
|
||||||
|
Write-Host " History: $RailwayUrl/api/data/history" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
Loading…
Reference in New Issue