437 lines
8.8 KiB
Markdown
437 lines
8.8 KiB
Markdown
# 🗓️ Panduan Sistem Penjadwalan Fleksibel
|
|
|
|
## ✨ Fitur Baru
|
|
|
|
Sistem penjadwalan sekarang **fully flexible**:
|
|
- ✅ **Dynamic schedules**: Tambah jadwal_1, jadwal_2, ... jadwal_N
|
|
- ✅ **Per-schedule pot selection**: Setiap jadwal bisa pilih pot mana yang aktif
|
|
- ✅ **Per-schedule configuration**: Tiap jadwal punya durasi & pompa sendiri
|
|
- ✅ **Enable/Disable**: Bisa matikan jadwal tanpa hapus data
|
|
- ✅ **No code change needed**: Tambah/ubah jadwal langsung di Firebase!
|
|
|
|
## 📋 Struktur Firebase Baru
|
|
|
|
### Contoh Sesuai Kebutuhan User:
|
|
|
|
```json
|
|
{
|
|
"kontrol": {
|
|
"waktu": true,
|
|
|
|
"jadwal_1": {
|
|
"aktif": true,
|
|
"waktu": "08:00",
|
|
"durasi": 60,
|
|
"pot_aktif": [1, 2, 3],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
|
|
"jadwal_2": {
|
|
"aktif": true,
|
|
"waktu": "09:00",
|
|
"durasi": 45,
|
|
"pot_aktif": [4, 5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
},
|
|
|
|
"jadwal_3": {
|
|
"aktif": true,
|
|
"waktu": "16:00",
|
|
"durasi": 30,
|
|
"pot_aktif": [1, 2, 3, 4, 5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Penjelasan Field:
|
|
|
|
| Field | Tipe | Wajib? | Default | Keterangan |
|
|
|-------|------|--------|---------|------------|
|
|
| `aktif` | boolean | ❌ | `true` | Enable/disable jadwal |
|
|
| `waktu` | string | ✅ | - | Format "HH:MM" (24 jam) |
|
|
| `durasi` | number | ❌ | `60` | Durasi penyiraman (detik) |
|
|
| `pot_aktif` | array | ✅ | - | Array pot yang aktif: `[1, 2, 3]` |
|
|
| `pompa_air` | boolean | ❌ | `true` | Nyalakan pompa air |
|
|
| `pompa_pupuk` | boolean | ❌ | `false` | Nyalakan pompa pupuk |
|
|
|
|
## 🚀 Cara Setup di Firebase
|
|
|
|
### 1. Buka Firebase Console
|
|
|
|
1. Go to: https://console.firebase.google.com
|
|
2. Pilih project **ApsGo**
|
|
3. Klik **Realtime Database**
|
|
4. Klik **Data** tab
|
|
|
|
### 2. Setup Struktur Awal
|
|
|
|
Klik di path `/kontrol` dan edit JSON:
|
|
|
|
```json
|
|
{
|
|
"kontrol": {
|
|
"waktu": true,
|
|
"sensor": false,
|
|
"otomatis": true,
|
|
|
|
"jadwal_1": {
|
|
"aktif": true,
|
|
"waktu": "08:00",
|
|
"durasi": 60,
|
|
"pot_aktif": [1, 2, 3],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
|
|
"jadwal_2": {
|
|
"aktif": true,
|
|
"waktu": "09:00",
|
|
"durasi": 45,
|
|
"pot_aktif": [4, 5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
},
|
|
|
|
"jadwal_3": {
|
|
"aktif": true,
|
|
"waktu": "16:00",
|
|
"durasi": 30,
|
|
"pot_aktif": [1, 2, 3, 4, 5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Tambah Jadwal Baru
|
|
|
|
Untuk tambah jadwal baru, tinggal tambah `jadwal_4`, `jadwal_5`, dst:
|
|
|
|
```json
|
|
"jadwal_4": {
|
|
"aktif": true,
|
|
"waktu": "12:00",
|
|
"durasi": 40,
|
|
"pot_aktif": [2, 4],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
}
|
|
```
|
|
|
|
**Tidak perlu restart worker!** Worker akan otomatis detect jadwal baru.
|
|
|
|
### 4. Disable Jadwal Sementara
|
|
|
|
Ubah `aktif` jadi `false`:
|
|
|
|
```json
|
|
"jadwal_3": {
|
|
"aktif": false,
|
|
"waktu": "16:00",
|
|
...
|
|
}
|
|
```
|
|
|
|
Jadwal tidak akan trigger, tapi data tetap tersimpan.
|
|
|
|
## 📱 Contoh Penggunaan
|
|
|
|
### Skenario 1: Pagi & Sore
|
|
|
|
**Kebutuhan:**
|
|
- Pagi (08:00): Semua pot disirami
|
|
- Sore (16:00): Hanya pot 1, 3, 5
|
|
|
|
**Setup:**
|
|
```json
|
|
"jadwal_1": {
|
|
"aktif": true,
|
|
"waktu": "08:00",
|
|
"durasi": 60,
|
|
"pot_aktif": [1, 2, 3, 4, 5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
"jadwal_2": {
|
|
"aktif": true,
|
|
"waktu": "16:00",
|
|
"durasi": 45,
|
|
"pot_aktif": [1, 3, 5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
}
|
|
```
|
|
|
|
### Skenario 2: Per-Pot Berbeda
|
|
|
|
**Kebutuhan:**
|
|
- Pot 1 & 2: Pagi (07:00), Siang (12:00), Sore (17:00)
|
|
- Pot 3 & 4: Pagi (08:00), Sore (16:00)
|
|
- Pot 5: Hanya pagi (09:00)
|
|
|
|
**Setup:**
|
|
```json
|
|
"jadwal_1": {
|
|
"aktif": true,
|
|
"waktu": "07:00",
|
|
"durasi": 60,
|
|
"pot_aktif": [1, 2],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
"jadwal_2": {
|
|
"aktif": true,
|
|
"waktu": "08:00",
|
|
"durasi": 60,
|
|
"pot_aktif": [3, 4],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
"jadwal_3": {
|
|
"aktif": true,
|
|
"waktu": "09:00",
|
|
"durasi": 60,
|
|
"pot_aktif": [5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
"jadwal_4": {
|
|
"aktif": true,
|
|
"waktu": "12:00",
|
|
"durasi": 45,
|
|
"pot_aktif": [1, 2],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
},
|
|
"jadwal_5": {
|
|
"aktif": true,
|
|
"waktu": "16:00",
|
|
"durasi": 50,
|
|
"pot_aktif": [3, 4],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
},
|
|
"jadwal_6": {
|
|
"aktif": true,
|
|
"waktu": "17:00",
|
|
"durasi": 40,
|
|
"pot_aktif": [1, 2],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
}
|
|
```
|
|
|
|
### Skenario 3: Testing
|
|
|
|
**Kebutuhan:** Test pot 3 saja setiap 15 menit
|
|
|
|
**Setup:**
|
|
```json
|
|
"jadwal_test_1": {
|
|
"aktif": true,
|
|
"waktu": "09:00",
|
|
"durasi": 10,
|
|
"pot_aktif": [3],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
"jadwal_test_2": {
|
|
"aktif": true,
|
|
"waktu": "09:15",
|
|
"durasi": 10,
|
|
"pot_aktif": [3],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
},
|
|
"jadwal_test_3": {
|
|
"aktif": true,
|
|
"waktu": "09:30",
|
|
"durasi": 10,
|
|
"pot_aktif": [3],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": false
|
|
}
|
|
```
|
|
|
|
## 🔍 Monitoring & Logs
|
|
|
|
### Log yang Normal:
|
|
|
|
```
|
|
⏱️ CHECK #15: 08:00:05 | Mode: ✅
|
|
📋 Total Jadwal: 3
|
|
✅ jadwal_1: 08:00 → Pot [1, 2, 3] 🔔 MATCH!
|
|
✅ jadwal_2: 09:00 → Pot [4, 5]
|
|
✅ jadwal_3: 16:00 → Pot [1, 2, 3, 4, 5]
|
|
|
|
🕐 JADWAL_1 TRIGGERED: 08:00
|
|
🎯 Pot aktif: [1, 2, 3]
|
|
⏱️ Durasi: 60s
|
|
💧 Pompa Air: ON
|
|
🌿 Pompa Pupuk: OFF
|
|
✅ Successfully added to queue: jadwal_1_2026-02-16_08_00
|
|
```
|
|
|
|
### Log Jika Jadwal Disabled:
|
|
|
|
```
|
|
⏱️ CHECK #15: 08:00:05 | Mode: ✅
|
|
📋 Total Jadwal: 3
|
|
❌ jadwal_1: 08:00 → Pot [1, 2, 3]
|
|
✅ jadwal_2: 09:00 → Pot [4, 5]
|
|
✅ jadwal_3: 16:00 → Pot [1, 2, 3, 4, 5]
|
|
```
|
|
|
|
### Log Error/Warning:
|
|
|
|
```
|
|
⚠️ jadwal_4: Invalid structure, skipping
|
|
⚠️ jadwal_5: No active pots defined, skipping
|
|
```
|
|
|
|
## ⚙️ Advanced Configuration
|
|
|
|
### Limit Maksimal Jadwal
|
|
|
|
Tidak ada limit! Bisa tambah jadwal_1 sampai jadwal_100 kalau perlu.
|
|
|
|
**Rekomendasi:**
|
|
- **Normal use**: 3-10 jadwal
|
|
- **Complex greenhouse**: 10-20 jadwal
|
|
- **Maximum tested**: 50 jadwal (still fast!)
|
|
|
|
### Naming Convention
|
|
|
|
Worker detect semua key yang mulai dengan `jadwal_`:
|
|
- ✅ `jadwal_1`, `jadwal_2`, `jadwal_3`
|
|
- ✅ `jadwal_pagi`, `jadwal_sore`, `jadwal_malam`
|
|
- ✅ `jadwal_test_1`, `jadwal_test_2`
|
|
- ❌ `schedule_1` (tidak akan terdetect)
|
|
|
|
### Validasi Otomatis
|
|
|
|
Worker otomatis validasi:
|
|
- ✅ `aktif` field (skip jika `false`)
|
|
- ✅ `waktu` field (skip jika tidak ada atau tidak match)
|
|
- ✅ `pot_aktif` array (skip jika kosong atau invalid)
|
|
- ✅ Default values untuk field opsional
|
|
|
|
## 🔄 Migration dari Format Lama
|
|
|
|
### Format Lama (Legacy):
|
|
|
|
```json
|
|
{
|
|
"kontrol": {
|
|
"waktu": true,
|
|
"waktu_1": "08:00",
|
|
"durasi_1": 60,
|
|
"waktu_2": "16:00",
|
|
"durasi_2": 45
|
|
}
|
|
}
|
|
```
|
|
|
|
**Masih supported!** Worker tetap baca `waktu_1` dan `waktu_2`.
|
|
|
|
### Migrasi Bertahap:
|
|
|
|
1. **Tetap pakai format lama** sambil test format baru
|
|
2. **Tambah jadwal baru** dengan format baru
|
|
3. **Disable format lama** setelah yakin
|
|
4. **Hapus format lama** setelah beberapa hari
|
|
|
|
### Contoh Transisi:
|
|
|
|
```json
|
|
{
|
|
"kontrol": {
|
|
"waktu": true,
|
|
|
|
// Format lama (masih jalan!)
|
|
"waktu_1": "08:00",
|
|
"durasi_1": 60,
|
|
|
|
// Format baru
|
|
"jadwal_2": {
|
|
"aktif": true,
|
|
"waktu": "09:00",
|
|
"durasi": 45,
|
|
"pot_aktif": [4, 5],
|
|
"pompa_air": true,
|
|
"pompa_pupuk": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🛠️ Troubleshooting
|
|
|
|
### Jadwal tidak trigger
|
|
|
|
**Check:**
|
|
1. ✅ `kontrol.waktu` = `true`?
|
|
2. ✅ `jadwal_X.aktif` = `true`?
|
|
3. ✅ `jadwal_X.waktu` format "HH:MM" (2 digit)?
|
|
4. ✅ `jadwal_X.pot_aktif` array tidak kosong?
|
|
5. ✅ Worker running di Railway?
|
|
|
|
### Pot salah yang menyala
|
|
|
|
**Check:**
|
|
1. ✅ `pot_aktif` array benar? `[1, 2, 3]` bukan `["1", "2", "3"]`
|
|
2. ✅ Tidak ada jadwal lain yang trigger di waktu sama?
|
|
3. ✅ Check logs: "Pot aktif: [...]"
|
|
|
|
### Durasi tidak sesuai
|
|
|
|
**Check:**
|
|
1. ✅ `durasi` dalam detik (bukan menit!)
|
|
2. ✅ Format number bukan string: `60` bukan `"60"`
|
|
|
|
## 📊 Performa
|
|
|
|
- **Check interval**: 60 detik
|
|
- **Detection time**: < 1 detik
|
|
- **Queue processing**: Sequential (1 job at a time)
|
|
- **Max schedules tested**: 50 jadwal
|
|
- **Memory impact**: Minimal (~5MB per 10 jadwal)
|
|
|
|
## 🚀 Deploy
|
|
|
|
Setelah edit struktur Firebase:
|
|
|
|
1. **Worker otomatis detect** jadwal baru (dalam 60 detik)
|
|
2. **No restart needed**
|
|
3. **Check logs** untuk verifikasi
|
|
|
|
Push perubahan worker.js ke Railway:
|
|
|
|
```bash
|
|
cd railway-worker
|
|
git add worker.js
|
|
git commit -m "feat: Add flexible multi-schedule support"
|
|
git push origin main
|
|
```
|
|
|
|
Railway auto-deploy dalam 2-3 menit.
|
|
|
|
## 📝 Summary
|
|
|
|
✅ **Flexible**: Tambah jadwal kapanpun tanpa ubah kode
|
|
✅ **Scalable**: Support 1-100+ jadwal
|
|
✅ **Per-schedule config**: Tiap jadwal bisa beda settingan
|
|
✅ **Backward compatible**: Format lama tetap jalan
|
|
✅ **Easy to use**: Setup langsung di Firebase
|
|
✅ **Production ready**: Sudah include error handling & validation
|
|
|
|
---
|
|
|
|
**Need help?** Check logs di Railway atau Firebase console untuk debug.
|