diff --git a/backend/DEPLOY_PERBAIKAN.md b/backend/DEPLOY_PERBAIKAN.md new file mode 100644 index 0000000..4393105 --- /dev/null +++ b/backend/DEPLOY_PERBAIKAN.md @@ -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` diff --git a/backend/deploy-to-railway.ps1 b/backend/deploy-to-railway.ps1 new file mode 100644 index 0000000..283b9ab --- /dev/null +++ b/backend/deploy-to-railway.ps1 @@ -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 "" diff --git a/backend/server.js b/backend/server.js index 2f4dd02..e6d4c93 100644 --- a/backend/server.js +++ b/backend/server.js @@ -107,7 +107,8 @@ mqttClient.on('connect', () => { mqttClient.subscribe([ MQTT_TOPICS.data, MQTT_TOPICS.status, - MQTT_TOPICS.button + MQTT_TOPICS.button, + MQTT_TOPICS.control ], (err) => { if (err) { console.error('❌ Failed to subscribe:', err); @@ -116,6 +117,7 @@ mqttClient.on('connect', () => { console.log(' -', MQTT_TOPICS.data); console.log(' -', MQTT_TOPICS.status); 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); } } + + // ===================================================== + // 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); } } + + // ===================================================== + // 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); + } + } + } } }); diff --git a/backend/test-control-topic.ps1 b/backend/test-control-topic.ps1 new file mode 100644 index 0000000..4f1ce2d --- /dev/null +++ b/backend/test-control-topic.ps1 @@ -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 ""