josss banget anjir

This commit is contained in:
kleponijo 2026-05-22 14:16:09 +07:00
parent c5413cdf95
commit 121d64798b
5 changed files with 79 additions and 0 deletions

View File

@ -34,6 +34,7 @@ class DeviceSetupBloc extends Bloc<DeviceSetupEvent, DeviceSetupState> {
(e, emit) => emit(state.copyWith(intervalHistoryMs: e.ms))); (e, emit) => emit(state.copyWith(intervalHistoryMs: e.ms)));
on<DeviceSettingsSaved>(_onSettingsSaved); on<DeviceSettingsSaved>(_onSettingsSaved);
on<DeviceLogsRefreshed>(_onLogsRefreshed); on<DeviceLogsRefreshed>(_onLogsRefreshed);
on<DeviceRestartRequested>(_onRestartRequested);
} }
// //
@ -235,6 +236,22 @@ class DeviceSetupBloc extends Bloc<DeviceSetupEvent, DeviceSetupState> {
} }
} }
Future<void> _onRestartRequested(
DeviceRestartRequested event,
Emitter<DeviceSetupState> 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 // Reset state
void _onReset( void _onReset(
ResetDeviceSetupEvent event, ResetDeviceSetupEvent event,

View File

@ -56,3 +56,5 @@ class DeviceSettingsSaved extends DeviceSetupEvent {}
/// Refresh logs dari Firebase /// Refresh logs dari Firebase
class DeviceLogsRefreshed extends DeviceSetupEvent {} class DeviceLogsRefreshed extends DeviceSetupEvent {}
class DeviceRestartRequested extends DeviceSetupEvent {}

View File

@ -529,6 +529,42 @@ class _LogsTab extends StatelessWidget {
final DeviceSetupState state; final DeviceSetupState state;
const _LogsTab({required this.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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final bloc = context.read<DeviceSetupBloc>(); final bloc = context.read<DeviceSetupBloc>();
@ -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( IconButton.filledTonal(
onPressed: state.logsLoading onPressed: state.logsLoading
? null ? null

View File

@ -92,6 +92,7 @@ class FirebaseMonitoringRepo implements MonitoringRepository {
} }
// Tulis settings ke Firebase (dari app) // Tulis settings ke Firebase (dari app)
@override
Future<void> updateAnemometerSettings({ Future<void> updateAnemometerSettings({
double? kFaktor, double? kFaktor,
double? radiusM, double? radiusM,
@ -110,6 +111,7 @@ class FirebaseMonitoringRepo implements MonitoringRepository {
} }
// Ambil logs dari device tertentu // Ambil logs dari device tertentu
@override
Future<List<Map<String, dynamic>>> getDeviceLogs( Future<List<Map<String, dynamic>>> getDeviceLogs(
String deviceId, { String deviceId, {
int limit = 50, int limit = 50,
@ -142,4 +144,9 @@ class FirebaseMonitoringRepo implements MonitoringRepository {
} catch (_) {} } catch (_) {}
return []; return [];
} }
@override
Future<void> sendRemoteRestart(String deviceId) async {
await _db.ref('anemometer/$deviceId/command/restart').set(true);
}
} }

View File

@ -38,4 +38,6 @@ abstract class MonitoringRepository {
String deviceId, { String deviceId, {
int limit = 50, int limit = 50,
}); });
Future<void> sendRemoteRestart(String deviceId);
} }