340 lines
12 KiB
Dart
340 lines
12 KiB
Dart
import 'package:firebase_database/firebase_database.dart';
|
|
import 'package:jago/services/db_helper.dart';
|
|
import 'dart:async';
|
|
|
|
class HistoryService {
|
|
static final HistoryService _instance = HistoryService._internal();
|
|
factory HistoryService() => _instance;
|
|
|
|
final DatabaseHelper dbHelper = DatabaseHelper();
|
|
final DatabaseReference _database = FirebaseDatabase.instance.ref();
|
|
|
|
// Status saat ini
|
|
Map<String, dynamic> currentRelay = {'Lampu': false, 'Kipas': false};
|
|
Map<String, dynamic> currentControl = {
|
|
'fan': {'auto': true, 'status': false},
|
|
'light': {'auto': true, 'status': false}
|
|
};
|
|
int ageInWeeks = 2;
|
|
|
|
// Daftar subscription untuk dibersihkan saat dispose
|
|
final List<StreamSubscription> _subscriptions = [];
|
|
|
|
// Flag untuk menandai apakah service sudah diinisialisasi
|
|
bool _isInitialized = false;
|
|
|
|
HistoryService._internal();
|
|
|
|
Future<void> initialize() async {
|
|
if (_isInitialized) return;
|
|
|
|
print("🚀 Menginisialisasi HistoryService...");
|
|
|
|
// Ambil umur ayam dari Firebase
|
|
_fetchAgeFromFirebase();
|
|
|
|
// Mulai memantau data
|
|
_listenForRelayStatus();
|
|
_listenForControlStatus();
|
|
_listenForStatusUpdates();
|
|
_listenForLogs();
|
|
|
|
_isInitialized = true;
|
|
print("✅ HistoryService berhasil diinisialisasi");
|
|
}
|
|
|
|
void dispose() {
|
|
for (var subscription in _subscriptions) {
|
|
subscription.cancel();
|
|
}
|
|
_subscriptions.clear();
|
|
_isInitialized = false;
|
|
print("🛑 HistoryService dihentikan");
|
|
}
|
|
|
|
void _fetchAgeFromFirebase() {
|
|
final subscription = _database.child("chicken_age").onValue.listen((event) {
|
|
final data = event.snapshot.value;
|
|
if (data != null) {
|
|
ageInWeeks = int.parse(data.toString());
|
|
print("🐔 Umur ayam diperbarui: $ageInWeeks minggu");
|
|
}
|
|
});
|
|
_subscriptions.add(subscription);
|
|
}
|
|
|
|
void _listenForRelayStatus() {
|
|
final subscription = _database.child('relay').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
try {
|
|
final Map<dynamic, dynamic> relayData = event.snapshot.value as Map;
|
|
bool lampStatus = relayData['Lampu'] is bool ? relayData['Lampu'] : relayData['Lampu'].toString().toLowerCase() == 'true';
|
|
bool fanStatus = relayData['Kipas'] is bool ? relayData['Kipas'] : relayData['Kipas'].toString().toLowerCase() == 'true';
|
|
|
|
// Periksa apakah status berubah
|
|
if (lampStatus != currentRelay['Lampu'] || fanStatus != currentRelay['Kipas']) {
|
|
String eventDescription = '[RELAY] Lampu ${lampStatus ? "Hidup" : "Mati"}, Kipas ${fanStatus ? "Hidup" : "Mati"}';
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': lampStatus ? 1 : 0,
|
|
'kipas': fanStatus ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data relay berhasil disimpan: $newEntry");
|
|
|
|
// Update status saat ini
|
|
currentRelay['Lampu'] = lampStatus;
|
|
currentRelay['Kipas'] = fanStatus;
|
|
}
|
|
} catch (e) {
|
|
print('❌ Error processing relay data: $e');
|
|
}
|
|
}
|
|
}, onError: (error) {
|
|
print('❌ Error listening to relay: $error');
|
|
});
|
|
|
|
_subscriptions.add(subscription);
|
|
}
|
|
|
|
void _listenForControlStatus() {
|
|
final subscription = _database.child('control').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
try {
|
|
final Map<dynamic, dynamic> controlData = event.snapshot.value as Map;
|
|
|
|
// Ambil status kontrol kipas
|
|
bool fanAuto = controlData['fan']['auto'] is bool ?
|
|
controlData['fan']['auto'] :
|
|
controlData['fan']['auto'].toString().toLowerCase() == 'true';
|
|
|
|
bool fanStatus = controlData['fan']['status'] is bool ?
|
|
controlData['fan']['status'] :
|
|
controlData['fan']['status'].toString().toLowerCase() == 'true';
|
|
|
|
// Ambil status kontrol lampu
|
|
bool lightAuto = controlData['light']['auto'] is bool ?
|
|
controlData['light']['auto'] :
|
|
controlData['light']['auto'].toString().toLowerCase() == 'true';
|
|
|
|
bool lightStatus = controlData['light']['status'] is bool ?
|
|
controlData['light']['status'] :
|
|
controlData['light']['status'].toString().toLowerCase() == 'true';
|
|
|
|
// Periksa apakah status berubah
|
|
bool fanAutoChanged = fanAuto != currentControl['fan']['auto'];
|
|
bool fanStatusChanged = fanStatus != currentControl['fan']['status'];
|
|
bool lightAutoChanged = lightAuto != currentControl['light']['auto'];
|
|
bool lightStatusChanged = lightStatus != currentControl['light']['status'];
|
|
|
|
if (fanAutoChanged || fanStatusChanged || lightAutoChanged || lightStatusChanged) {
|
|
String eventDescription = '[CONTROL] ';
|
|
|
|
if (fanAutoChanged) {
|
|
eventDescription += 'Kipas mode ${fanAuto ? "Otomatis" : "Manual"}, ';
|
|
}
|
|
|
|
if (fanStatusChanged && !fanAuto) {
|
|
eventDescription += 'Kipas ${fanStatus ? "ON" : "OFF"}, ';
|
|
}
|
|
|
|
if (lightAutoChanged) {
|
|
eventDescription += 'Lampu mode ${lightAuto ? "Otomatis" : "Manual"}, ';
|
|
}
|
|
|
|
if (lightStatusChanged && !lightAuto) {
|
|
eventDescription += 'Lampu ${lightStatus ? "ON" : "OFF"}, ';
|
|
}
|
|
|
|
// Hapus koma dan spasi di akhir
|
|
eventDescription = eventDescription.replaceAll(RegExp(r', $'), '');
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': lightStatus ? 1 : 0,
|
|
'kipas': fanStatus ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data control berhasil disimpan: $newEntry");
|
|
|
|
// Update status saat ini
|
|
currentControl['fan']['auto'] = fanAuto;
|
|
currentControl['fan']['status'] = fanStatus;
|
|
currentControl['light']['auto'] = lightAuto;
|
|
currentControl['light']['status'] = lightStatus;
|
|
}
|
|
} catch (e) {
|
|
print('❌ Error processing control data: $e');
|
|
}
|
|
}
|
|
}, onError: (error) {
|
|
print('❌ Error listening to control: $error');
|
|
});
|
|
|
|
_subscriptions.add(subscription);
|
|
}
|
|
|
|
void _listenForStatusUpdates() {
|
|
// Pantau status suhu
|
|
final subscription = _database.child('status/temperature').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
String status = event.snapshot.value.toString();
|
|
String eventDescription = '[STATUS] Suhu: $status';
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': currentRelay['Lampu'] ? 1 : 0,
|
|
'kipas': currentRelay['Kipas'] ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data status suhu berhasil disimpan: $newEntry");
|
|
}
|
|
});
|
|
|
|
_subscriptions.add(subscription);
|
|
|
|
// Pantau status kelembapan
|
|
final subscription2 = _database.child('status/humidity').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
String status = event.snapshot.value.toString();
|
|
String eventDescription = '[STATUS] Kelembapan: $status';
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': currentRelay['Lampu'] ? 1 : 0,
|
|
'kipas': currentRelay['Kipas'] ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data status kelembapan berhasil disimpan: $newEntry");
|
|
}
|
|
});
|
|
|
|
_subscriptions.add(subscription2);
|
|
}
|
|
|
|
void _listenForLogs() {
|
|
// Pantau log sistem
|
|
final logsRef = _database.child('logs');
|
|
|
|
// Pantau log WiFi
|
|
final subscription = logsRef.child('wifi').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
String logMessage = event.snapshot.value.toString();
|
|
String eventDescription = '[SYSTEM] WiFi: $logMessage';
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': currentRelay['Lampu'] ? 1 : 0,
|
|
'kipas': currentRelay['Kipas'] ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data log WiFi berhasil disimpan: $newEntry");
|
|
}
|
|
});
|
|
|
|
_subscriptions.add(subscription);
|
|
|
|
// Pantau log sensor
|
|
final subscription2 = logsRef.child('sensor').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
String logMessage = event.snapshot.value.toString();
|
|
String eventDescription = '[SENSOR] $logMessage';
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': currentRelay['Lampu'] ? 1 : 0,
|
|
'kipas': currentRelay['Kipas'] ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data log sensor berhasil disimpan: $newEntry");
|
|
}
|
|
});
|
|
|
|
_subscriptions.add(subscription2);
|
|
|
|
// Pantau log LCD
|
|
final subscription3 = logsRef.child('lcd').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
String logMessage = event.snapshot.value.toString();
|
|
String eventDescription = '[SYSTEM] LCD: $logMessage';
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': currentRelay['Lampu'] ? 1 : 0,
|
|
'kipas': currentRelay['Kipas'] ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data log LCD berhasil disimpan: $newEntry");
|
|
}
|
|
});
|
|
|
|
_subscriptions.add(subscription3);
|
|
|
|
// Pantau log sistem
|
|
final subscription4 = logsRef.child('system').onValue.listen((event) {
|
|
if (event.snapshot.value != null) {
|
|
String logMessage = event.snapshot.value.toString();
|
|
String eventDescription = '[SYSTEM] $logMessage';
|
|
|
|
// Tambahkan informasi umur ayam
|
|
eventDescription += " [Umur: $ageInWeeks minggu]";
|
|
|
|
Map<String, dynamic> newEntry = {
|
|
'timestamp': DateTime.now().toIso8601String(),
|
|
'lampu': currentRelay['Lampu'] ? 1 : 0,
|
|
'kipas': currentRelay['Kipas'] ? 1 : 0,
|
|
'event': eventDescription
|
|
};
|
|
|
|
// Simpan ke database lokal
|
|
dbHelper.insertHistory(newEntry);
|
|
print("✅ Data log sistem berhasil disimpan: $newEntry");
|
|
}
|
|
});
|
|
|
|
_subscriptions.add(subscription4);
|
|
}
|
|
} |