From 121d64798b492c3fde8fad00ed8a93944078b3e4 Mon Sep 17 00:00:00 2001 From: kleponijo <158453666+kleponijo@users.noreply.github.com> Date: Fri, 22 May 2026 14:16:09 +0700 Subject: [PATCH] josss banget anjir --- .../device_setup/blocs/device_setup_bloc.dart | 17 +++++++ .../blocs/device_setup_event.dart | 2 + .../views/device_setup_screen.dart | 51 +++++++++++++++++++ .../lib/src/firebase_monitoring_repo.dart | 7 +++ .../lib/src/monitoring_repo.dart | 2 + 5 files changed, 79 insertions(+) diff --git a/lib/screens/monitoring/device_setup/blocs/device_setup_bloc.dart b/lib/screens/monitoring/device_setup/blocs/device_setup_bloc.dart index a722682..bb1c890 100644 --- a/lib/screens/monitoring/device_setup/blocs/device_setup_bloc.dart +++ b/lib/screens/monitoring/device_setup/blocs/device_setup_bloc.dart @@ -34,6 +34,7 @@ class DeviceSetupBloc extends Bloc { (e, emit) => emit(state.copyWith(intervalHistoryMs: e.ms))); on(_onSettingsSaved); on(_onLogsRefreshed); + on(_onRestartRequested); } // ════════════════════════════════════════════════════════════ @@ -235,6 +236,22 @@ class DeviceSetupBloc extends Bloc { } } + Future _onRestartRequested( + DeviceRestartRequested event, + Emitter emit, + ) async { + try { + await _repository.sendRemoteRestart(state.deviceId); + emit(state.copyWith(status: DeviceSetupStatus.settingsSaved)); + // Reuse status settingsSaved untuk snackbar — atau bisa buat status baru + } catch (e) { + emit(state.copyWith( + status: DeviceSetupStatus.settingsError, + errorMessage: 'Gagal kirim restart: $e', + )); + } + } + // ── Reset state ─────────────────────────────────────────────── void _onReset( ResetDeviceSetupEvent event, diff --git a/lib/screens/monitoring/device_setup/blocs/device_setup_event.dart b/lib/screens/monitoring/device_setup/blocs/device_setup_event.dart index f1378cd..e426d38 100644 --- a/lib/screens/monitoring/device_setup/blocs/device_setup_event.dart +++ b/lib/screens/monitoring/device_setup/blocs/device_setup_event.dart @@ -56,3 +56,5 @@ class DeviceSettingsSaved extends DeviceSetupEvent {} /// Refresh logs dari Firebase class DeviceLogsRefreshed extends DeviceSetupEvent {} + +class DeviceRestartRequested extends DeviceSetupEvent {} diff --git a/lib/screens/monitoring/device_setup/views/device_setup_screen.dart b/lib/screens/monitoring/device_setup/views/device_setup_screen.dart index 85ac403..2caa196 100644 --- a/lib/screens/monitoring/device_setup/views/device_setup_screen.dart +++ b/lib/screens/monitoring/device_setup/views/device_setup_screen.dart @@ -529,6 +529,42 @@ class _LogsTab extends StatelessWidget { final DeviceSetupState state; const _LogsTab({required this.state}); + void _showRestartDialog( + BuildContext context, DeviceSetupBloc bloc, String deviceId) { + showDialog( + context: context, + builder: (ctx) => AlertDialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + title: const Row(children: [ + Icon(Icons.restart_alt_rounded, color: Colors.red), + SizedBox(width: 8), + Text('Remote Restart'), + ]), + content: Text( + 'ESP "$deviceId" akan restart dalam ~5 detik.\n\n' + 'Data realtime akan berhenti sebentar lalu kembali normal.', + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(ctx), + child: Text('Batal', style: TextStyle(color: Colors.grey.shade600)), + ), + ElevatedButton( + onPressed: () { + Navigator.pop(ctx); + bloc.add(DeviceRestartRequested()); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.red.shade600, + foregroundColor: Colors.white, + ), + child: const Text('Restart'), + ), + ], + ), + ); + } + @override Widget build(BuildContext context) { final bloc = context.read(); @@ -556,6 +592,21 @@ class _LogsTab extends StatelessWidget { ], ), ), + + // restart esp + IconButton.filledTonal( + onPressed: () => + _showRestartDialog(context, bloc, state.deviceId), + icon: const Icon(Icons.restart_alt_rounded), + tooltip: 'Remote Restart ESP', + style: IconButton.styleFrom( + backgroundColor: Colors.red.shade50, + foregroundColor: Colors.red.shade700, + ), + ), + const SizedBox(width: 8), + + // refresh log serial IconButton.filledTonal( onPressed: state.logsLoading ? null diff --git a/packages/monitoring_repository/lib/src/firebase_monitoring_repo.dart b/packages/monitoring_repository/lib/src/firebase_monitoring_repo.dart index f13be47..a0f9f43 100644 --- a/packages/monitoring_repository/lib/src/firebase_monitoring_repo.dart +++ b/packages/monitoring_repository/lib/src/firebase_monitoring_repo.dart @@ -92,6 +92,7 @@ class FirebaseMonitoringRepo implements MonitoringRepository { } // ── Tulis settings ke Firebase (dari app) ──────────────────── + @override Future updateAnemometerSettings({ double? kFaktor, double? radiusM, @@ -110,6 +111,7 @@ class FirebaseMonitoringRepo implements MonitoringRepository { } // ── Ambil logs dari device tertentu ────────────────────────── + @override Future>> getDeviceLogs( String deviceId, { int limit = 50, @@ -142,4 +144,9 @@ class FirebaseMonitoringRepo implements MonitoringRepository { } catch (_) {} return []; } + + @override + Future sendRemoteRestart(String deviceId) async { + await _db.ref('anemometer/$deviceId/command/restart').set(true); + } } diff --git a/packages/monitoring_repository/lib/src/monitoring_repo.dart b/packages/monitoring_repository/lib/src/monitoring_repo.dart index 62e06ce..7db0f76 100644 --- a/packages/monitoring_repository/lib/src/monitoring_repo.dart +++ b/packages/monitoring_repository/lib/src/monitoring_repo.dart @@ -38,4 +38,6 @@ abstract class MonitoringRepository { String deviceId, { int limit = 50, }); + + Future sendRemoteRestart(String deviceId); }