import 'dart:async'; 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/ceiling_sensor/bloc/event.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/state.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart'; import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/help_description.dart'; import 'package:syncrow_web/services/devices_mang_api.dart'; class CeilingSensorBloc extends Bloc { final String deviceId; late CeilingSensorModel deviceStatus; Timer? _timer; CeilingSensorBloc({required this.deviceId}) : super(CeilingInitialState()) { on(_fetchCeilingSensorStatus); on(_fetchCeilingSensorBatchControl); on(_changeValue); on(_onBatchControl); on(_getDeviceReports); on(_showDescription); on(_backToGridView); on(_onFactoryReset); } void _fetchCeilingSensorStatus(CeilingInitialEvent event, Emitter emit) async { emit(CeilingLoadingInitialState()); try { var response = await DevicesManagementApi().getDeviceStatus(event.deviceId); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); // _listenToChanges(); } catch (e) { emit(CeilingFailedState(error: e.toString())); return; } } // _listenToChanges() { // try { // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); // Stream stream = ref.onValue; // stream.listen((DatabaseEvent event) { // Map usersMap = event.snapshot.value as Map; // List statusList = []; // usersMap['status'].forEach((element) { // statusList.add(StatusModel(code: element['code'], value: element['value'])); // }); // deviceStatus = WallSensorModel.fromJson(statusList); // add(WallSensorUpdatedEvent()); // }); // } catch (_) {} // } void _changeValue(CeilingChangeValueEvent event, Emitter emit) async { emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus)); if (event.code == 'sensitivity') { deviceStatus.sensitivity = event.value; } else if (event.code == 'none_body_time') { deviceStatus.noBodyTime = event.value; } else if (event.code == 'moving_max_dis') { deviceStatus.maxDistance = event.value; } else if (event.code == 'scene') { deviceStatus.spaceType = getSpaceType(event.value); } emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); await _runDeBouncer( deviceId: deviceId, code: event.code, value: event.value, emit: emit, isBatch: false, ); } Future _onBatchControl(CeilingBatchControlEvent event, Emitter emit) async { emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus)); if (event.code == 'sensitivity') { deviceStatus.sensitivity = event.value; } else if (event.code == 'none_body_time') { deviceStatus.noBodyTime = event.value; } else if (event.code == 'moving_max_dis') { deviceStatus.maxDistance = event.value; } else if (event.code == 'scene') { deviceStatus.spaceType = getSpaceType(event.value); } emit(CeilingUpdateState(ceilingSensorModel: 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, }) { late String id; if (deviceId is List) { id = deviceId.first; } else { id = deviceId; } 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(CeilingInitialEvent(id)); } if (response == true && code == 'scene') { emit(CeilingLoadingInitialState()); await Future.delayed(const Duration(seconds: 1)); add(CeilingInitialEvent(id)); } } catch (_) { await Future.delayed(const Duration(milliseconds: 500)); add(CeilingInitialEvent(id)); } }); } FutureOr _getDeviceReports(GetCeilingDeviceReportsEvent event, Emitter emit) async { if (event.code.isEmpty) { emit(ShowCeilingDescriptionState(description: reportString)); return; } else { emit(CeilingReportsLoadingState()); 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()) .then((value) { emit(CeilingReportsState(deviceReport: value)); }); } catch (e) { emit(CeilingReportsFailedState(error: e.toString())); return; } } } void _showDescription(ShowCeilingDescriptionEvent event, Emitter emit) { emit(ShowCeilingDescriptionState(description: event.description)); } void _backToGridView(BackToCeilingGridViewEvent event, Emitter emit) { emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); } FutureOr _fetchCeilingSensorBatchControl( CeilingFetchDeviceStatusEvent event, Emitter emit) async { emit(CeilingLoadingInitialState()); try { var response = await DevicesManagementApi().getBatchStatus(event.devicesIds); deviceStatus = CeilingSensorModel.fromJson(response.status); emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); } catch (e) { emit(CeilingFailedState(error: e.toString())); return; } } FutureOr _onFactoryReset(CeilingFactoryResetEvent event, Emitter emit) async { emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus)); try { final response = await DevicesManagementApi().factoryReset( event.factoryResetModel, event.devicesId, ); if (!response) { emit(const CeilingFailedState(error: 'Failed')); } else { emit(CeilingUpdateState(ceilingSensorModel: deviceStatus)); } } catch (e) { emit(CeilingFailedState(error: e.toString())); } } }