diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart new file mode 100644 index 00000000..06be2666 --- /dev/null +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_bloc.dart @@ -0,0 +1,266 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:firebase_database/firebase_database.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_reports.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/factory_reset_model.dart'; +import 'package:syncrow_web/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart'; +import 'package:syncrow_web/services/control_device_service.dart'; +import 'package:syncrow_web/services/devices_mang_api.dart'; + +part 'flush_mounted_presence_sensor_event.dart'; +part 'flush_mounted_presence_sensor_state.dart'; + +class FlushMountedPresenceSensorBloc + extends Bloc { + final String deviceId; + late FlushMountedPresenceSensorModel deviceStatus; + + final ControlDeviceService controlDeviceService; + + FlushMountedPresenceSensorBloc({ + required this.deviceId, + required this.controlDeviceService, + }) : super(FlushMountedPresenceSensorInitialState()) { + on( + _onFlushMountedPresenceSensorFetchStatusEvent, + ); + on( + _onFlushMountedPresenceSensorFetchBatchStatusEvent); + on( + _onFlushMountedPresenceSensorChangeValueEvent, + ); + on( + _onFlushMountedPresenceSensorBatchControlEvent, + ); + on( + _onFlushMountedPresenceSensorGetDeviceReportsEvent); + on( + _onFlushMountedPresenceSensorShowDescriptionEvent, + ); + on( + _onFlushMountedPresenceSensorBackToGridViewEvent, + ); + on( + _onFlushMountedPresenceSensorFactoryResetEvent, + ); + } + + void _onFlushMountedPresenceSensorFetchStatusEvent( + FlushMountedPresenceSensorFetchStatusEvent event, + Emitter emit, + ) async { + emit(FlushMountedPresenceSensorLoadingInitialState()); + try { + final response = await DevicesManagementApi().getDeviceStatus(deviceId); + deviceStatus = FlushMountedPresenceSensorModel.fromJson(response.status); + emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); + _listenToChanges(emit, deviceId); + } catch (e) { + emit(FlushMountedPresenceSensorFailedState(error: e.toString())); + return; + } + } + + Future _onFlushMountedPresenceSensorFetchBatchStatusEvent( + FlushMountedPresenceSensorFetchBatchStatusEvent event, + Emitter emit, + ) async { + emit(FlushMountedPresenceSensorLoadingInitialState()); + try { + var response = await DevicesManagementApi().getBatchStatus(event.devicesIds); + deviceStatus = FlushMountedPresenceSensorModel.fromJson(response.status); + emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); + } catch (e) { + emit(FlushMountedPresenceSensorFailedState(error: e.toString())); + } + } + + void _listenToChanges( + Emitter emit, + String deviceId, + ) { + try { + final ref = FirebaseDatabase.instance.ref( + 'device-status/$deviceId', + ); + + ref.onValue.listen((DatabaseEvent event) { + Map usersMap = + event.snapshot.value as Map; + List statusList = []; + + usersMap['status'].forEach((element) { + statusList.add(Status(code: element['code'], value: element['value'])); + }); + + deviceStatus = FlushMountedPresenceSensorModel.fromJson(statusList); + emit(FlushMountedPresenceSensorLoadingNewSate(model: deviceStatus)); + }); + } catch (_) {} + } + + void _onFlushMountedPresenceSensorChangeValueEvent( + FlushMountedPresenceSensorChangeValueEvent event, + Emitter emit, + ) async { + emit(FlushMountedPresenceSensorLoadingNewSate(model: deviceStatus)); + switch (event.code) { + case FlushMountedPresenceSensorModel.codeFarDetection: + deviceStatus.farDetection = event.value; + break; + case FlushMountedPresenceSensorModel.codeSensitivity: + log('updated sensitivity: ${deviceStatus.sensitivity}-${event.value}'); + deviceStatus.sensitivity = event.value; + break; + case FlushMountedPresenceSensorModel.codeNoneDelay: + log('updated none delay: ${deviceStatus.noneDelay}-${event.value}'); + deviceStatus.noneDelay = event.value; + break; + case FlushMountedPresenceSensorModel.codePresenceDelay: + deviceStatus.presenceDelay = event.value; + break; + case FlushMountedPresenceSensorModel.codeNearDetection: + deviceStatus.nearDetection = event.value; + break; + case FlushMountedPresenceSensorModel.codeOccurDistReduce: + deviceStatus.occurDistReduce = event.value; + break; + case FlushMountedPresenceSensorModel.codeSensiReduce: + deviceStatus.sensiReduce = event.value; + break; + default: + break; + } + emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); + await _runDeBouncer( + deviceId: deviceId, + code: event.code, + value: event.value, + isBatch: false, + emit: emit, + ); + } + + Future _onFlushMountedPresenceSensorBatchControlEvent( + FlushMountedPresenceSensorBatchControlEvent event, + Emitter emit, + ) async { + emit(FlushMountedPresenceSensorLoadingNewSate(model: deviceStatus)); + switch (event.code) { + case FlushMountedPresenceSensorModel.codeFarDetection: + deviceStatus.farDetection = event.value; + break; + case FlushMountedPresenceSensorModel.codeSensitivity: + deviceStatus.sensitivity = event.value; + break; + case FlushMountedPresenceSensorModel.codeNoneDelay: + deviceStatus.noneDelay = event.value; + break; + case FlushMountedPresenceSensorModel.codePresenceDelay: + deviceStatus.presenceDelay = event.value; + break; + case FlushMountedPresenceSensorModel.codeNearDetection: + deviceStatus.nearDetection = event.value; + break; + case FlushMountedPresenceSensorModel.codeOccurDistReduce: + deviceStatus.occurDistReduce = event.value; + break; + case FlushMountedPresenceSensorModel.codeSensiReduce: + deviceStatus.sensiReduce = event.value; + break; + default: + break; + } + emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); + await _runDeBouncer( + deviceId: event.deviceIds, + code: event.code, + value: event.value, + emit: emit, + isBatch: true, + ); + } + + Future _runDeBouncer({ + required dynamic deviceId, + required String code, + required dynamic value, + required Emitter emit, + required bool isBatch, + }) async { + try { + if (isBatch) { + await DevicesManagementApi().deviceBatchControl(deviceId, code, value); + } else { + await controlDeviceService.controlDevice( + deviceUuid: deviceId, + status: Status(code: code, value: value), + ); + } + } catch (_) { + await Future.delayed(const Duration(milliseconds: 500)); + add(FlushMountedPresenceSensorFetchStatusEvent()); + } + } + + Future _onFlushMountedPresenceSensorGetDeviceReportsEvent( + FlushMountedPresenceSensorGetDeviceReportsEvent event, + Emitter emit, + ) async { + emit(FlushMountedPresenceSensorDeviceReportsLoadingState()); + + try { + await DevicesManagementApi.getDeviceReports(deviceId, event.code) + .then((value) { + emit(FlushMountedPresenceSensorDeviceReportsState( + deviceReport: value, code: event.code)); + }); + } catch (e) { + emit(FlushMountedPresenceSensorDeviceReportsFailedState(error: e.toString())); + return; + } + } + + void _onFlushMountedPresenceSensorShowDescriptionEvent( + FlushMountedPresenceSensorShowDescriptionEvent event, + Emitter emit, + ) { + emit(FlushMountedPresenceSensorShowDescriptionState( + description: event.description)); + } + + void _onFlushMountedPresenceSensorBackToGridViewEvent( + FlushMountedPresenceSensorBackToGridViewEvent event, + Emitter emit, + ) { + emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); + } + + Future _onFlushMountedPresenceSensorFactoryResetEvent( + FlushMountedPresenceSensorFactoryResetEvent event, + Emitter emit, + ) async { + emit(FlushMountedPresenceSensorLoadingNewSate(model: deviceStatus)); + try { + final response = await DevicesManagementApi().factoryReset( + event.factoryReset, + event.deviceId, + ); + if (!response) { + emit( + const FlushMountedPresenceSensorFailedState( + error: 'Something went wrong with factory reset, please try again', + ), + ); + } else { + emit(FlushMountedPresenceSensorUpdateState(model: deviceStatus)); + } + } catch (e) { + emit(FlushMountedPresenceSensorFailedState(error: e.toString())); + } + } +} diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart new file mode 100644 index 00000000..f1636300 --- /dev/null +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_event.dart @@ -0,0 +1,84 @@ +part of 'flush_mounted_presence_sensor_bloc.dart'; + +sealed class FlushMountedPresenceSensorEvent extends Equatable { + const FlushMountedPresenceSensorEvent(); + + @override + List get props => []; +} + +class FlushMountedPresenceSensorFetchStatusEvent + extends FlushMountedPresenceSensorEvent {} + +class FlushMountedPresenceSensorChangeValueEvent + extends FlushMountedPresenceSensorEvent { + final int value; + final String code; + final bool isBatchControl; + const FlushMountedPresenceSensorChangeValueEvent({ + required this.value, + required this.code, + this.isBatchControl = false, + }); + + @override + List get props => [value, code]; +} + +class FlushMountedPresenceSensorFetchBatchStatusEvent + extends FlushMountedPresenceSensorEvent { + final List devicesIds; + const FlushMountedPresenceSensorFetchBatchStatusEvent(this.devicesIds); + + @override + List get props => [devicesIds]; +} + +class FlushMountedPresenceSensorGetDeviceReportsEvent + extends FlushMountedPresenceSensorEvent { + final String deviceUuid; + final String code; + const FlushMountedPresenceSensorGetDeviceReportsEvent({ + required this.deviceUuid, + required this.code, + }); + + @override + List get props => [deviceUuid, code]; +} + +class FlushMountedPresenceSensorShowDescriptionEvent + extends FlushMountedPresenceSensorEvent { + final String description; + const FlushMountedPresenceSensorShowDescriptionEvent({required this.description}); +} + +class FlushMountedPresenceSensorBackToGridViewEvent + extends FlushMountedPresenceSensorEvent {} + +class FlushMountedPresenceSensorBatchControlEvent + extends FlushMountedPresenceSensorEvent { + final List deviceIds; + final String code; + final dynamic value; + + const FlushMountedPresenceSensorBatchControlEvent({ + required this.deviceIds, + required this.code, + required this.value, + }); + + @override + List get props => [deviceIds, code, value]; +} + +class FlushMountedPresenceSensorFactoryResetEvent + extends FlushMountedPresenceSensorEvent { + final String deviceId; + final FactoryResetModel factoryReset; + + const FlushMountedPresenceSensorFactoryResetEvent({ + required this.deviceId, + required this.factoryReset, + }); +} diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart new file mode 100644 index 00000000..0fef07f2 --- /dev/null +++ b/lib/pages/device_managment/flush_mounted_presence_sensor/bloc/flush_mounted_presence_sensor_state.dart @@ -0,0 +1,76 @@ +part of 'flush_mounted_presence_sensor_bloc.dart'; + +sealed class FlushMountedPresenceSensorState extends Equatable { + const FlushMountedPresenceSensorState(); + + @override + List get props => []; +} + +class FlushMountedPresenceSensorInitialState + extends FlushMountedPresenceSensorState {} + +class FlushMountedPresenceSensorLoadingInitialState + extends FlushMountedPresenceSensorState {} + +class FlushMountedPresenceSensorUpdateState extends FlushMountedPresenceSensorState { + final FlushMountedPresenceSensorModel model; + const FlushMountedPresenceSensorUpdateState({required this.model}); + + @override + List get props => [model]; +} + +class FlushMountedPresenceSensorLoadingNewSate + extends FlushMountedPresenceSensorState { + final FlushMountedPresenceSensorModel model; + const FlushMountedPresenceSensorLoadingNewSate({required this.model}); + + @override + List get props => [model]; +} + +class FlushMountedPresenceSensorFailedState extends FlushMountedPresenceSensorState { + final String error; + + const FlushMountedPresenceSensorFailedState({required this.error}); + + @override + List get props => [error]; +} + +class FlushMountedPresenceSensorDeviceReportsLoadingState + extends FlushMountedPresenceSensorState {} + +class FlushMountedPresenceSensorDeviceReportsState + extends FlushMountedPresenceSensorState { + const FlushMountedPresenceSensorDeviceReportsState({ + required this.deviceReport, + required this.code, + }); + + final DeviceReport deviceReport; + final String code; + + @override + List get props => [deviceReport, code]; +} + +class FlushMountedPresenceSensorDeviceReportsFailedState + extends FlushMountedPresenceSensorState { + const FlushMountedPresenceSensorDeviceReportsFailedState({required this.error}); + + final String error; + + @override + List get props => [error]; +} + +class FlushMountedPresenceSensorShowDescriptionState + extends FlushMountedPresenceSensorState { + const FlushMountedPresenceSensorShowDescriptionState({required this.description}); + + final String description; + @override + List get props => [description]; +}