diff --git a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart index 5efe0848..2e3a8633 100644 --- a/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart +++ b/lib/pages/device_managment/two_gang_switch/bloc/two_gang_switch_bloc.dart @@ -48,9 +48,7 @@ class TwoGangSwitchBloc extends Bloc { void _listenToChanges(String deviceId) { try { - final ref = FirebaseDatabase.instance.ref( - 'device-status/$deviceId', - ); + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); ref.onValue.listen((event) { final eventsMap = event.snapshot.value as Map; @@ -58,10 +56,7 @@ class TwoGangSwitchBloc extends Bloc { List statusList = []; eventsMap['status'].forEach((element) { statusList.add( - Status( - code: element['code'], - value: element['value'].toString(), - ), + Status(code: element['code'], value: element['value']), ); }); diff --git a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart index 3c144142..630a132b 100644 --- a/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart +++ b/lib/pages/device_managment/wall_sensor/bloc/wall_bloc.dart @@ -1,18 +1,28 @@ import 'dart:async'; +import 'dart:developer'; + import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_event.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_state.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_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'; class WallSensorBloc extends Bloc { final String deviceId; - late WallSensorModel deviceStatus; - Timer? _timer; + final ControlDeviceService controlDeviceService; + final BatchControlDevicesService batchControlDevicesService; - WallSensorBloc({required this.deviceId}) : super(WallSensorInitialState()) { + late WallSensorModel deviceStatus; + + WallSensorBloc({ + required this.deviceId, + required this.controlDeviceService, + required this.batchControlDevicesService, + }) : super(WallSensorInitialState()) { on(_fetchWallSensorStatus); on(_fetchWallSensorBatchControl); on(_changeValue); @@ -24,28 +34,28 @@ class WallSensorBloc extends Bloc { on(_onRealtimeUpdate); } - void _fetchWallSensorStatus( - WallSensorFetchStatusEvent event, Emitter emit) async { + Future _fetchWallSensorStatus( + WallSensorFetchStatusEvent event, + Emitter emit, + ) async { emit(WallSensorLoadingInitialState()); try { - var response = await DevicesManagementApi().getDeviceStatus(deviceId); + final response = await DevicesManagementApi().getDeviceStatus(deviceId); deviceStatus = WallSensorModel.fromJson(response.status); - emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); _listenToChanges(deviceId); + emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); } catch (e) { emit(WallSensorFailedState(error: e.toString())); - return; } } - // Fetch batch status - FutureOr _fetchWallSensorBatchControl( - WallSensorFetchBatchStatusEvent event, - Emitter emit) async { + Future _fetchWallSensorBatchControl( + WallSensorFetchBatchStatusEvent event, + Emitter emit, + ) async { emit(WallSensorLoadingInitialState()); try { - var response = - await DevicesManagementApi().getBatchStatus(event.devicesIds); + final response = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = WallSensorModel.fromJson(response.status); emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); } catch (e) { @@ -54,132 +64,105 @@ class WallSensorBloc extends Bloc { } void _listenToChanges(String deviceId) { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$deviceId'); - ref.onValue.listen((DatabaseEvent event) { - final data = event.snapshot.value as Map?; - if (data == null) return; + try { + final ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); - final statusList = (data['status'] as List?) - ?.map((e) => Status(code: e['code'], value: e['value'])) - .toList(); + ref.onValue.listen((event) { + final eventsMap = event.snapshot.value as Map; - if (statusList != null) { - final updatedDeviceStatus = WallSensorModel.fromJson(statusList); + List statusList = []; + eventsMap['status'].forEach((element) { + statusList.add( + Status(code: element['code'], value: element['value']), + ); + }); + + deviceStatus = WallSensorModel.fromJson(statusList); if (!isClosed) { - add(WallSensorRealtimeUpdateEvent(updatedDeviceStatus)); + add(WallSensorRealtimeUpdateEvent(deviceStatus)); } - } - }); + }); + } catch (_) { + log( + 'Error listening to changes', + name: 'WallSensorBloc._listenToChanges', + ); + } } - - void _changeValue( - WallSensorChangeValueEvent event, Emitter emit) async { + Future _changeValue( + WallSensorChangeValueEvent event, + Emitter emit, + ) async { emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus)); - if (event.code == 'far_detection') { - deviceStatus.farDetection = event.value; - } else if (event.code == 'motionless_sensitivity') { - deviceStatus.motionlessSensitivity = event.value; - } else if (event.code == 'motion_sensitivity_value') { - deviceStatus.motionSensitivity = event.value; - } else if (event.code == 'no_one_time') { - deviceStatus.noBodyTime = event.value; - } + _updateLocalValue(event.code, event.value); emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); - await _runDeBouncer( - deviceId: deviceId, - code: event.code, - value: event.value, - isBatch: false, - emit: emit, - ); + + try { + await controlDeviceService.controlDevice( + deviceUuid: deviceId, + status: Status(code: event.code, value: event.value), + ); + } catch (e) { + _updateLocalValue(event.code, event.value == 0 ? 1 : 0); + emit(WallSensorFailedState(error: e.toString())); + } } Future _onBatchControl( - WallSensorBatchControlEvent event, Emitter emit) async { + WallSensorBatchControlEvent event, + Emitter emit, + ) async { emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus)); - if (event.code == 'far_detection') { - deviceStatus.farDetection = event.value; - } else if (event.code == 'motionless_sensitivity') { - deviceStatus.motionlessSensitivity = event.value; - } else if (event.code == 'motion_sensitivity_value') { - deviceStatus.motionSensitivity = event.value; - } else if (event.code == 'no_one_time') { - deviceStatus.noBodyTime = event.value; - } + _updateLocalValue(event.code, event.value); emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); - await _runDeBouncer( - deviceId: event.deviceIds, - code: event.code, - value: event.value, - emit: emit, - isBatch: true, - ); - } - - _runDeBouncer({ - required dynamic deviceId, - required String code, - required dynamic value, - required Emitter emit, - required bool isBatch, - }) { - if (_timer != null) { - _timer!.cancel(); - } - _timer = Timer(const Duration(seconds: 1), () async { - try { - late bool response; - if (isBatch) { - response = await DevicesManagementApi() - .deviceBatchControl(deviceId, code, value); - } else { - response = await DevicesManagementApi() - .deviceControl(deviceId, Status(code: code, value: value)); - } - - if (!response) { - add(WallSensorFetchStatusEvent()); - } - } catch (_) { - await Future.delayed(const Duration(milliseconds: 500)); - add(WallSensorFetchStatusEvent()); - } - }); - } - - FutureOr _getDeviceReports( - GetDeviceReportsEvent event, Emitter emit) async { - emit(DeviceReportsLoadingState()); - // final from = DateTime.now().subtract(const Duration(days: 30)).millisecondsSinceEpoch; - // final to = DateTime.now().millisecondsSinceEpoch; try { - // await DevicesManagementApi.getDeviceReportsByDate( - // deviceId, event.code, from.toString(), to.toString()) - await DevicesManagementApi.getDeviceReports(deviceId, event.code) - .then((value) { - emit(DeviceReportsState(deviceReport: value, code: event.code)); - }); + await batchControlDevicesService.batchControlDevices( + uuids: event.deviceIds, + code: event.code, + value: event.value, + ); + } catch (e) { + _updateLocalValue(event.code, !event.value); + emit(WallSensorFailedState(error: e.toString())); + } + } + + Future _getDeviceReports( + GetDeviceReportsEvent event, + Emitter emit, + ) async { + emit(DeviceReportsLoadingState()); + try { + final reports = await DevicesManagementApi.getDeviceReports( + deviceId, + event.code, + ); + emit(DeviceReportsState(deviceReport: reports, code: event.code)); } catch (e) { emit(DeviceReportsFailedState(error: e.toString())); - return; } } void _showDescription( - ShowDescriptionEvent event, Emitter emit) { + ShowDescriptionEvent event, + Emitter emit, + ) { emit(WallSensorShowDescriptionState(description: event.description)); } void _backToGridView( - BackToGridViewEvent event, Emitter emit) { + BackToGridViewEvent event, + Emitter emit, + ) { emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); } - FutureOr _onFactoryReset( - WallSensorFactoryResetEvent event, Emitter emit) async { + Future _onFactoryReset( + WallSensorFactoryResetEvent event, + Emitter emit, + ) async { emit(WallSensorLoadingNewSate(wallSensorModel: deviceStatus)); try { final response = await DevicesManagementApi().factoryReset( @@ -187,9 +170,9 @@ class WallSensorBloc extends Bloc { event.deviceId, ); if (!response) { - emit(const WallSensorFailedState(error: 'Failed')); + emit(const WallSensorFailedState(error: 'Failed to reset device')); } else { - emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); + add(WallSensorFetchStatusEvent()); } } catch (e) { emit(WallSensorFailedState(error: e.toString())); @@ -200,7 +183,23 @@ class WallSensorBloc extends Bloc { WallSensorRealtimeUpdateEvent event, Emitter emit, ) { - deviceStatus = event.deviceStatus; - emit(WallSensorUpdateState(wallSensorModel: deviceStatus)); + emit(WallSensorUpdateState(wallSensorModel: event.deviceStatus)); + } + + void _updateLocalValue(String code, dynamic value) { + switch (code) { + case 'far_detection': + deviceStatus.farDetection = value; + break; + case 'motionless_sensitivity': + deviceStatus.motionlessSensitivity = value; + break; + case 'motion_sensitivity_value': + deviceStatus.motionSensitivity = value; + break; + case 'no_one_time': + deviceStatus.noBodyTime = value; + break; + } } } diff --git a/lib/pages/device_managment/wall_sensor/factories/wall_sensor_bloc_factory.dart b/lib/pages/device_managment/wall_sensor/factories/wall_sensor_bloc_factory.dart new file mode 100644 index 00000000..d7811717 --- /dev/null +++ b/lib/pages/device_managment/wall_sensor/factories/wall_sensor_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/wall_sensor/bloc/wall_bloc.dart'; + +abstract final class WallSensorBlocFactory { + const WallSensorBlocFactory._(); + + static WallSensorBloc create({ + required String deviceId, + }) { + return WallSensorBloc( + deviceId: deviceId, + controlDeviceService: + DeviceBlocDependenciesFactory.createControlDeviceService(), + batchControlDevicesService: + DeviceBlocDependenciesFactory.createBatchControlDevicesService(), + ); + } +} diff --git a/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart b/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart index 27169f0e..61108387 100644 --- a/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart +++ b/lib/pages/device_managment/wall_sensor/view/wall_sensor_batch_control.dart @@ -7,6 +7,7 @@ import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presen import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_bloc.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_event.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/bloc/wall_state.dart'; +import 'package:syncrow_web/pages/device_managment/wall_sensor/factories/wall_sensor_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_model.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; @@ -21,7 +22,7 @@ class WallSensorBatchControlView extends StatelessWidget with HelperResponsiveLa final isLarge = isLargeScreenSize(context); final isMedium = isMediumScreenSize(context); return BlocProvider( - create: (context) => WallSensorBloc(deviceId: devicesIds.first) + create: (context) => WallSensorBlocFactory.create(deviceId: devicesIds.first) ..add(WallSensorFetchBatchStatusEvent(devicesIds)), child: BlocBuilder( builder: (context, state) { diff --git a/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart b/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart index 370edaa5..def8ed93 100644 --- a/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart +++ b/lib/pages/device_managment/wall_sensor/view/wall_sensor_conrtols.dart @@ -10,6 +10,7 @@ import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presen import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart'; import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_status.dart'; import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart'; +import 'package:syncrow_web/pages/device_managment/wall_sensor/factories/wall_sensor_bloc_factory.dart'; import 'package:syncrow_web/pages/device_managment/wall_sensor/model/wall_sensor_model.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart'; @@ -26,7 +27,7 @@ class WallSensorControlsView extends StatelessWidget with HelperResponsiveLayout final isMedium = isMediumScreenSize(context); return BlocProvider( create: (context) => - WallSensorBloc(deviceId: device.uuid!)..add(WallSensorFetchStatusEvent()), + WallSensorBlocFactory.create(deviceId: device.uuid!)..add(WallSensorFetchStatusEvent()), child: BlocBuilder( builder: (context, state) { if (state is WallSensorLoadingInitialState || state is DeviceReportsLoadingState) {