diff --git a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart index 18a0787f..38c7f2d6 100644 --- a/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart +++ b/lib/pages/device_managment/water_heater/bloc/water_heater_bloc.dart @@ -10,6 +10,8 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/device_sta import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_entry.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/schedule_model.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; +import 'package:syncrow_web/services/batch_control_devices_service.dart'; +import 'package:syncrow_web/services/control_device_service.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; import 'package:syncrow_web/utils/format_date_time.dart'; @@ -17,7 +19,17 @@ part 'water_heater_event.dart'; part 'water_heater_state.dart'; class WaterHeaterBloc extends Bloc { - WaterHeaterBloc() : super(WaterHeaterInitial()) { + late WaterHeaterStatusModel deviceStatus; + final String deviceId; + final ControlDeviceService controlDeviceService; + final BatchControlDevicesService batchControlDevicesService; + Timer? _countdownTimer; + + WaterHeaterBloc({ + required this.deviceId, + required this.controlDeviceService, + required this.batchControlDevicesService, + }) : super(WaterHeaterInitial()) { on(_fetchWaterHeaterStatus); on(_controlWaterHeater); on(_batchFetchWaterHeater); @@ -29,7 +41,6 @@ class WaterHeaterBloc extends Bloc { on(_updateSelectedTime); on(_updateSelectedDay); on(_updateFunctionOn); - on(_getSchedule); on(_onAddSchedule); on(_onEditSchedule); @@ -38,10 +49,6 @@ class WaterHeaterBloc extends Bloc { on(_onStatusUpdated); } - late WaterHeaterStatusModel deviceStatus; - Timer? _countdownTimer; - // Timer? _inchingTimer; - FutureOr _initializeAddSchedule( InitializeAddScheduleEvent event, Emitter emit, @@ -116,13 +123,11 @@ class WaterHeaterBloc extends Bloc { countdownRemaining: countdownRemaining, )); - if (!currentState.isCountdownActive! && - countdownRemaining > Duration.zero) { + if (!currentState.isCountdownActive! && countdownRemaining > Duration.zero) { _startCountdownTimer(emit, countdownRemaining); } } else if (event.scheduleMode == ScheduleModes.inching) { - final inchingDuration = - Duration(hours: event.hours, minutes: event.minutes); + final inchingDuration = Duration(hours: event.hours, minutes: event.minutes); emit(currentState.copyWith( scheduleMode: ScheduleModes.inching, @@ -141,21 +146,18 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - final oldValue = _getValueByCode(event.code); - _updateLocalValue(event.code, event.value); emit(currentState.copyWith( status: deviceStatus, )); - final success = await _runDebounce( - deviceId: event.deviceId, - code: event.code, - value: event.value, - oldValue: oldValue, - emit: emit, - isBatch: false, + final success = await controlDeviceService.controlDevice( + deviceUuid: event.deviceId, + status: Status( + code: event.code, + value: event.value, + ), ); if (success) { @@ -182,15 +184,11 @@ class WaterHeaterBloc extends Bloc { } } else if (event.code == "switch_inching") { final inchingDuration = Duration(seconds: event.value); - //if (inchingDuration.inSeconds > 0) { - // _startInchingTimer(emit, inchingDuration); - // } else { emit(currentState.copyWith( inchingHours: inchingDuration.inHours, inchingMinutes: inchingDuration.inMinutes % 60, isInchingActive: true, )); - // } } } } @@ -224,8 +222,7 @@ class WaterHeaterBloc extends Bloc { try { final status = await DevicesManagementApi().deviceControl( event.deviceId, - Status( - code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), + Status(code: isCountDown ? 'countdown_1' : 'switch_inching', value: 0), ); if (!status) { emit(const WaterHeaterFailedState(error: 'Failed to stop schedule.')); @@ -243,10 +240,8 @@ class WaterHeaterBloc extends Bloc { emit(WaterHeaterLoadingState()); try { - final status = - await DevicesManagementApi().getDeviceStatus(event.deviceId); - deviceStatus = - WaterHeaterStatusModel.fromJson(event.deviceId, status.status); + final status = await DevicesManagementApi().getDeviceStatus(event.deviceId); + deviceStatus = WaterHeaterStatusModel.fromJson(event.deviceId, status.status); if (deviceStatus.scheduleMode == ScheduleModes.countdown) { final countdownRemaining = Duration( @@ -288,7 +283,6 @@ class WaterHeaterBloc extends Bloc { inchingMinutes: deviceStatus.inchingMinutes, isInchingActive: true, )); -//_startInchingTimer(emit, inchingDuration); } else { emit(WaterHeaterDeviceStatusLoaded( deviceStatus, @@ -316,7 +310,7 @@ class WaterHeaterBloc extends Bloc { } } - _listenToChanges(deviceId) { + void _listenToChanges(deviceId) { try { DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); @@ -328,12 +322,11 @@ class WaterHeaterBloc extends Bloc { List statusList = []; usersMap['status'].forEach((element) { - statusList - .add(Status(code: element['code'], value: element['value'])); + statusList.add(Status(code: element['code'], value: element['value'])); }); - deviceStatus = WaterHeaterStatusModel.fromJson( - usersMap['productUuid'], statusList); + deviceStatus = + WaterHeaterStatusModel.fromJson(usersMap['productUuid'], statusList); if (!isClosed) { add(StatusUpdated(deviceStatus)); } @@ -357,17 +350,6 @@ class WaterHeaterBloc extends Bloc { }); } - // void _startInchingTimer( - // Emitter emit, - // Duration inchingDuration, - // ) { - // _inchingTimer?.cancel(); - - // _inchingTimer = Timer.periodic(const Duration(minutes: 1), (timer) { - // add(DecrementInchingEvent()); - // }); - // } - _onDecrementCountdown( DecrementCountdownEvent event, Emitter emit, @@ -405,85 +387,6 @@ class WaterHeaterBloc extends Bloc { } } - // FutureOr _onDecrementInching( - // DecrementInchingEvent event, - // Emitter emit, - // ) { - // if (state is WaterHeaterDeviceStatusLoaded) { - // final currentState = state as WaterHeaterDeviceStatusLoaded; - - // if (currentState.inchingHours > 0 || currentState.inchingMinutes > 0) { - // final newRemaining = Duration( - // hours: currentState.inchingHours, - // minutes: currentState.inchingMinutes, - // ) - - // const Duration(minutes: 1); - - // if (newRemaining <= Duration.zero) { - // _inchingTimer?.cancel(); - // emit(currentState.copyWith( - // inchingHours: 0, - // inchingMinutes: 0, - // isInchingActive: false, - // )); - // } else { - // emit(currentState.copyWith( - // inchingHours: newRemaining.inHours, - // inchingMinutes: newRemaining.inMinutes % 60, - // )); - // } - // } - // } - // } - - Future _runDebounce({ - required dynamic deviceId, - required String code, - required dynamic value, - required dynamic oldValue, - required Emitter emit, - required bool isBatch, - }) async { - try { - late bool status; - await Future.delayed(const Duration(milliseconds: 500)); - - if (isBatch) { - status = await DevicesManagementApi().deviceBatchControl( - deviceId, - code, - value, - ); - } else { - status = await DevicesManagementApi().deviceControl( - deviceId, - Status(code: code, value: value), - ); - } - - if (!status) { - _revertValue(code, oldValue, emit.call); - return false; - } else { - return true; - } - } catch (e) { - _revertValue(code, oldValue, emit.call); - return false; - } - } - - void _revertValue(String code, dynamic oldValue, - void Function(WaterHeaterState state) emit) { - _updateLocalValue(code, oldValue); - if (state is WaterHeaterDeviceStatusLoaded) { - final currentState = state as WaterHeaterDeviceStatusLoaded; - emit(currentState.copyWith( - status: deviceStatus, - )); - } - } - void _updateLocalValue(String code, dynamic value) { switch (code) { case 'switch_1': @@ -505,14 +408,12 @@ class WaterHeaterBloc extends Bloc { } dynamic _getValueByCode(String code) { - switch (code) { - case 'switch_1': - return deviceStatus.heaterSwitch; - case 'countdown_1': - return deviceStatus.countdownHours * 60 + deviceStatus.countdownMinutes; - default: - return null; - } + return switch (code) { + 'switch_1' => deviceStatus.heaterSwitch, + 'countdown_1' => + (deviceStatus.countdownHours * 60) + deviceStatus.countdownMinutes, + _ => null, + }; } @override @@ -571,8 +472,10 @@ class WaterHeaterBloc extends Bloc { } } - FutureOr _onEditSchedule(EditWaterHeaterScheduleEvent event, - Emitter emit) async { + FutureOr _onEditSchedule( + EditWaterHeaterScheduleEvent event, + Emitter emit, + ) async { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; @@ -584,8 +487,6 @@ class WaterHeaterBloc extends Bloc { days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays), ); - // emit(ScheduleLoadingState()); - bool success = await DevicesManagementApi().editScheduleRecord( currentState.status.uuid, newSchedule, @@ -595,7 +496,6 @@ class WaterHeaterBloc extends Bloc { add(GetSchedulesEvent(category: 'switch_1', uuid: deviceStatus.uuid)); } else { emit(currentState); - //emit(const WaterHeaterFailedState(error: 'Failed to add schedule.')); } } } @@ -627,7 +527,6 @@ class WaterHeaterBloc extends Bloc { emit(currentState.copyWith(schedules: updatedSchedules)); } else { emit(currentState); - // emit(const WaterHeaterFailedState(error: 'Failed to update schedule.')); } } } @@ -639,8 +538,6 @@ class WaterHeaterBloc extends Bloc { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; - // emit(ScheduleLoadingState()); - bool success = await DevicesManagementApi() .deleteScheduleRecord(currentState.status.uuid, event.scheduleId); @@ -652,20 +549,18 @@ class WaterHeaterBloc extends Bloc { emit(currentState.copyWith(schedules: updatedSchedules)); } else { emit(currentState); - // emit(const WaterHeaterFailedState(error: 'Failed to delete schedule.')); } } } - FutureOr _batchFetchWaterHeater(FetchWaterHeaterBatchStatusEvent event, - Emitter emit) async { + FutureOr _batchFetchWaterHeater( + FetchWaterHeaterBatchStatusEvent event, Emitter emit) async { emit(WaterHeaterLoadingState()); try { - final status = - await DevicesManagementApi().getBatchStatus(event.devicesUuid); - deviceStatus = WaterHeaterStatusModel.fromJson( - event.devicesUuid.first, status.status); + final status = await DevicesManagementApi().getBatchStatus(event.devicesUuid); + deviceStatus = + WaterHeaterStatusModel.fromJson(event.devicesUuid.first, status.status); emit(WaterHeaterDeviceStatusLoaded(deviceStatus)); } catch (e) { @@ -673,8 +568,8 @@ class WaterHeaterBloc extends Bloc { } } - FutureOr _batchControlWaterHeater(ControlWaterHeaterBatchEvent event, - Emitter emit) async { + FutureOr _batchControlWaterHeater( + ControlWaterHeaterBatchEvent event, Emitter emit) async { if (state is WaterHeaterDeviceStatusLoaded) { final currentState = state as WaterHeaterDeviceStatusLoaded; @@ -686,13 +581,10 @@ class WaterHeaterBloc extends Bloc { status: deviceStatus, )); - final success = await _runDebounce( - deviceId: event.devicesUuid, + final success = await batchControlDevicesService.batchControlDevices( + uuids: event.devicesUuid, code: event.code, value: event.value, - oldValue: oldValue, - emit: emit, - isBatch: true, ); if (success) { diff --git a/lib/pages/device_managment/water_heater/factories/water_heater_bloc_factory.dart b/lib/pages/device_managment/water_heater/factories/water_heater_bloc_factory.dart new file mode 100644 index 00000000..9c0c8ab6 --- /dev/null +++ b/lib/pages/device_managment/water_heater/factories/water_heater_bloc_factory.dart @@ -0,0 +1,18 @@ +import 'package:syncrow_web/pages/device_managment/factories/device_bloc_dependencies_factory.dart'; +import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; + +abstract final class WaterHeaterBlocFactory { + const WaterHeaterBlocFactory._(); + + static WaterHeaterBloc create({ + required String deviceId, + }) { + return WaterHeaterBloc( + deviceId: deviceId, + controlDeviceService: + DeviceBlocDependenciesFactory.createControlDeviceService(), + batchControlDevicesService: + DeviceBlocDependenciesFactory.createBatchControlDevicesService(), + ); + } +} diff --git a/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart b/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart index aaab5271..3c8a3858 100644 --- a/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart +++ b/lib/pages/device_managment/water_heater/view/water_heater_batch_control.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; - import 'package:syncrow_web/pages/device_managment/shared/batch_control/factory_reset.dart'; // import 'package:syncrow_web/pages/device_managment/shared/batch_control/firmware_update.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/water_heater/factories/water_heater_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; -class WaterHEaterBatchControlView extends StatelessWidget with HelperResponsiveLayout { +class WaterHEaterBatchControlView extends StatelessWidget + with HelperResponsiveLayout { const WaterHEaterBatchControlView({super.key, required this.deviceIds}); final List deviceIds; @@ -17,8 +18,9 @@ class WaterHEaterBatchControlView extends StatelessWidget with HelperResponsiveL @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - WaterHeaterBloc()..add(FetchWaterHeaterBatchStatusEvent(devicesUuid: deviceIds)), + create: (context) => WaterHeaterBlocFactory.create( + deviceId: deviceIds.first, + )..add(FetchWaterHeaterBatchStatusEvent(devicesUuid: deviceIds)), child: BlocBuilder( builder: (context, state) { if (state is WaterHeaterLoadingState) { diff --git a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart index 40d3edb5..f1e56136 100644 --- a/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart +++ b/lib/pages/device_managment/water_heater/view/water_heater_device_control.dart @@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_mo import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart'; import 'package:syncrow_web/pages/device_managment/shared/toggle_widget.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/bloc/water_heater_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/water_heater/factories/water_heater_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/models/water_heater_status_model.dart'; import 'package:syncrow_web/pages/device_managment/water_heater/widgets/schedual_view.dart'; import 'package:syncrow_web/utils/color_manager.dart'; @@ -21,8 +22,9 @@ class WaterHeaterDeviceControlView extends StatelessWidget @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => - WaterHeaterBloc()..add(WaterHeaterFetchStatusEvent(device.uuid!)), + create: (context) => WaterHeaterBlocFactory.create( + deviceId: device.uuid ?? '', + )..add(WaterHeaterFetchStatusEvent(device.uuid!)), child: BlocBuilder( builder: (context, state) { if (state is WaterHeaterLoadingState) { @@ -33,8 +35,7 @@ class WaterHeaterDeviceControlView extends StatelessWidget state is WaterHeaterBatchFailedState) { return const Center(child: Text('Error fetching status')); } else { - return const SizedBox( - height: 200, child: Center(child: SizedBox())); + return const SizedBox(height: 200, child: Center(child: SizedBox())); } }, ));