260 lines
5.5 KiB
Markdown
260 lines
5.5 KiB
Markdown
# 🔄 TelurKu - Firebase Real-Time Sensor Integration FINAL
|
|
|
|
## 📊 Implementasi Lengkap
|
|
|
|
Semua fitur siap untuk **real-time monitoring** telur dari Firebase sensors!
|
|
|
|
### ✅ Yang Sudah Diimplementasikan:
|
|
|
|
#### **1. KandangProvider - Sensor Listener**
|
|
```dart
|
|
// Sensor Real-time Listeners
|
|
int _infra1Value = 0; // Nilai telur dari infra1
|
|
int _infra2Value = 0; // Nilai telur dari infra2
|
|
|
|
int get infra1Value => _infra1Value;
|
|
int get infra2Value => _infra2Value;
|
|
|
|
// Listen ke 'data' folder semua waktu
|
|
void listenToSensors() {
|
|
_sensorSubscription = _database.ref('data').onValue.listen((event) {
|
|
if (event.snapshot.exists) {
|
|
final data = Map<dynamic, dynamic>.from(event.snapshot.value as Map);
|
|
_infra1Value = data['infra1'] ?? 0;
|
|
_infra2Value = data['infra2'] ?? 0;
|
|
notifyListeners(); // UI terupdate otomatis!
|
|
}
|
|
});
|
|
}
|
|
```
|
|
|
|
#### **2. Kandang Model - Support infraPath**
|
|
```dart
|
|
class Kandang {
|
|
final String id;
|
|
final String nama;
|
|
final int jumlahAyam;
|
|
final DateTime dibuat;
|
|
final String? infraPath; // ← Optional path ke sensor
|
|
}
|
|
```
|
|
|
|
#### **3. Dashboard - Tampil Data Real-Time**
|
|
- **Total Telur Hari Ini**: `infra1Value + infra2Value`
|
|
- **Status Kandang 1**: `infra1Value`
|
|
- **Status Kandang 2**: `infra2Value`
|
|
- Auto-update tanpa perlu refresh!
|
|
|
|
---
|
|
|
|
## 🚀 Cara Kerja
|
|
|
|
### Flow Data:
|
|
```
|
|
Firebase Database (data/infra1: 59, data/infra2: 78)
|
|
↓
|
|
KandangProvider.listenToSensors()
|
|
↓
|
|
Update _infra1Value & _infra2Value
|
|
↓
|
|
notifyListeners() — Trigger UI rebuild
|
|
↓
|
|
Dashboard tampil telur real-time ✨
|
|
```
|
|
|
|
### Integrasi Sensor:
|
|
```
|
|
Kandang1 (index 0) ←→ infra1 (Firebase data/infra1)
|
|
Kandang2 (index 1) ←→ infra2 (Firebase data/infra2)
|
|
```
|
|
|
|
---
|
|
|
|
## 📲 Setup Firebase
|
|
|
|
### 1. Pastikan Data Ada di Firebase Console:
|
|
|
|
```
|
|
your_project/
|
|
├── data/
|
|
│ ├── infra1: 59 ← Sensor telur kandang 1
|
|
│ ├── infra2: 78 ← Sensor telur kandang 2
|
|
│ └── infraX: <value>
|
|
```
|
|
|
|
### 2. Buat 2 Kandang di Aplikasi:
|
|
|
|
**Kandang Pertama:**
|
|
- Nama: "Kandang1" (atau nama apapun)
|
|
- Jumlah Ayam: 50
|
|
- Firebase Path (optional): data/infra1
|
|
|
|
**Kandang Kedua:**
|
|
- Nama: "Kandang2"
|
|
- Jumlah Ayam: 48
|
|
- Firebase Path (optional): data/infra2
|
|
|
|
### 3. Test Sensor Real-Time:
|
|
|
|
1. Buka Dashboard di app
|
|
2. Lihat "Status Kandang" menampilkan telur
|
|
3. Update nilai di Firebase Console
|
|
4. Dashboard auto-update dalam **1-2 detik** ⚡
|
|
|
|
---
|
|
|
|
## 🔧 Lifecycle
|
|
|
|
### Saat User Login:
|
|
```
|
|
initializeWithUser(userId)
|
|
├─ Load kandang dari Firebase
|
|
├─ Setup kandang listener
|
|
└─ Call listenToSensors() ← Mulai listen sensor
|
|
```
|
|
|
|
### Saat Dashboard Dibuka:
|
|
```
|
|
Dashboard build()
|
|
└─ Watch KandangProvider
|
|
├─ Ambil infra1Value
|
|
├─ Ambil infra2Value
|
|
└─ Update UI (notifyListeners() trigger rebuild)
|
|
```
|
|
|
|
### Saat User Logout:
|
|
```
|
|
clearData()
|
|
├─ Cancel kandang listener
|
|
├─ Cancel sensor listener ← Berhenti listen
|
|
└─ Reset semua values ke 0
|
|
```
|
|
|
|
---
|
|
|
|
## 📝 Key Methods
|
|
|
|
### Di KandangProvider:
|
|
|
|
```dart
|
|
// Mulai listening ke sensor
|
|
void listenToSensors() {
|
|
_database.ref('data').onValue.listen((event) {
|
|
_infra1Value = data['infra1'] ?? 0;
|
|
_infra2Value = data['infra2'] ?? 0;
|
|
notifyListeners();
|
|
});
|
|
}
|
|
|
|
// Setter kandang tetap support infraPath
|
|
void addKandang(String nama, int jumlahAyam, {String? infraPath})
|
|
|
|
void updateKandang(String id, String nama, int jumlahAyam, {String? infraPath})
|
|
|
|
// Cleanup saat logout
|
|
Future<void> clearData() {
|
|
_sensorSubscription?.cancel();
|
|
_infra1Value = 0;
|
|
_infra2Value = 0;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Mapping Kandang ↔ Sensor
|
|
|
|
| Kandang | Index | Sensor | Path | Property |
|
|
|---------|-------|--------|------|----------|
|
|
| Kandang1 | 0 | infra1 | data/infra1 | infra1Value |
|
|
| Kandang2 | 1 | infra2 | data/infra2 | infra2Value |
|
|
|
|
---
|
|
|
|
## 🔍 Dashboard Display
|
|
|
|
### Total Telur Hari Ini:
|
|
```
|
|
kandangProvider.infra1Value + kandangProvider.infra2Value
|
|
= 59 + 78
|
|
= 137 🥚
|
|
```
|
|
|
|
### Status Kandang:
|
|
```
|
|
Kandang1
|
|
├─ 50 ekor ayam
|
|
└─ 59 Telur (dari infra1) ← Real-time!
|
|
|
|
Kandang2
|
|
├─ 48 ekor ayam
|
|
└─ 78 Telur (dari infra2) ← Real-time!
|
|
```
|
|
|
|
---
|
|
|
|
## ⚙️ Firebase Rules
|
|
|
|
Pastikan rules allow read:
|
|
|
|
```json
|
|
{
|
|
"rules": {
|
|
"data": {
|
|
".read": true,
|
|
".write": "auth != null"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🧪 Testing
|
|
|
|
### Manual Test:
|
|
1. Running app
|
|
2. Lihat Dashboard → Total Telur = sum(infra1, infra2)
|
|
3. Edit Firebase: infra1 dari 59 → 100
|
|
4. Dashboard → Total berubah ke 178 secara otomatis!
|
|
|
|
### Debug Log:
|
|
```
|
|
// Di KandangProvider
|
|
print('infra1Value: $_infra1Value');
|
|
print('infra2Value: $_infra2Value');
|
|
print('Total: ${_infra1Value + _infra2Value}');
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 File Yang Berubah
|
|
|
|
```
|
|
lib/
|
|
├── models/
|
|
│ └── kandang_model.dart ✅ Added infraPath field
|
|
├── providers/
|
|
│ └── kandang_provider.dart ✅ Added sensor listeners (MAIN!)
|
|
│ ├─ _infra1Value, _infra2Value
|
|
│ ├─ listenToSensors()
|
|
│ ├─ initializeWithUser() calls listenToSensors()
|
|
│ └─ dispose() cancels listener
|
|
└── screens/
|
|
└── dashboard_page.dart ✅ Updated untuk tampil sensor values
|
|
├─ Total: infra1Value + infra2Value
|
|
└─ Per kandang: index-based (0→infra1, 1→infra2)
|
|
```
|
|
|
|
---
|
|
|
|
## 🎉 Result
|
|
|
|
**Dashboard sekarang:**
|
|
- ✅ Real-time update dari Firebase sensors
|
|
- ✅ Tidak perlu refresh manual
|
|
- ✅ Auto-sync perubahan sensor
|
|
- ✅ Clean & efficient implementation
|
|
- ✅ Proper cleanup saat logout
|
|
|
|
**Setup Complete!** 🚀
|