diff --git a/lib/screens/monitoring/wind_speed_monitoring_screen.dart b/lib/screens/monitoring/wind_speed_monitoring_screen.dart index e705988..4e32b88 100644 --- a/lib/screens/monitoring/wind_speed_monitoring_screen.dart +++ b/lib/screens/monitoring/wind_speed_monitoring_screen.dart @@ -3,6 +3,7 @@ import 'package:fl_chart/fl_chart.dart'; import 'package:firebase_database/firebase_database.dart'; import 'dart:async'; import 'widgets/monitoring_shared.dart'; +import 'package:intl/intl.dart'; /// WIND SPEED MONITORING SCREEN class WindSpeedMonitoringScreen extends StatefulWidget { @@ -18,10 +19,18 @@ class _WindSpeedMonitoringScreenState extends State { // realtime database state final DatabaseReference _realtimeRef = FirebaseDatabase.instance.ref('anemometer/realtime'); StreamSubscription? _realtimeSub; - // current speed kept for future display if needed - // double _currentSpeed = 0.0; + + // realtime values + DateTime? _lastUpdateTime; + double _currentSpeed = 0.0; final List _dailySpeeds = List.filled(24, 0.0); + bool get _isOnline { + if (_lastUpdateTime == null) return false; + final diff = DateTime.now().difference(_lastUpdateTime!); + return diff.inSeconds <= 5; + } + @override void initState() { @@ -31,10 +40,19 @@ class _WindSpeedMonitoringScreenState extends State { void _onRealtimeData(DatabaseEvent event) { final data = event.snapshot.value; + if (data is Map) { final speed = (data['kecepatan'] ?? 0).toDouble(); + final timestamp = data['timestamp'] ?? 0; + + final waktu = DateTime.fromMillisecondsSinceEpoch( + timestamp * 1000, + ); + setState(() { - // shift hourly data, keep latest at end + _currentSpeed = speed; + _lastUpdateTime = waktu; + _dailySpeeds.removeAt(0); _dailySpeeds.add(speed); }); @@ -68,7 +86,63 @@ class _WindSpeedMonitoringScreenState extends State { ), ), const SizedBox(height: 20), - + if (_lastUpdateTime != null) + Padding( + padding: const EdgeInsets.only(bottom: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "${_currentSpeed.toStringAsFixed(2)} km/h", + style: const TextStyle( + fontSize: 28, + fontWeight: FontWeight.bold, + color: Colors.green, + ), + ), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, + vertical: 5, + ), + decoration: BoxDecoration( + color: _isOnline + ? Colors.green.shade100 + : Colors.red.shade100, + borderRadius: BorderRadius.circular(20), + ), + child: Text( + _isOnline ? "ONLINE" : "OFFLINE", + style: TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: _isOnline ? Colors.green : Colors.red, + ), + ), + ), + ], + ), + const SizedBox(height: 4), + Builder( + builder: (_) { + final formattedTime = DateFormat( + "dd MMM yyyy • HH:mm:ss", + ).format(_lastUpdateTime!); + return Text( + "Update: $formattedTime", + style: const TextStyle( + fontSize: 12, + color: Colors.grey, + ), + ); + }, + ), + ], + ), + ), /// GRAFIK MONITORING _buildMonitoringGraphBlock(), const SizedBox(height: 25), diff --git a/pubspec.lock b/pubspec.lock index 7d18d73..f2d3ad9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -280,6 +280,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" leak_tracker: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 00cde00..699ec7f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: cupertino_icons: ^1.0.8 fl_chart: ^1.1.1 firebase_database: ^12.1.3 + intl: ^0.20.2 dev_dependencies: flutter_test: