diff --git a/lib/features/devices/bloc/acs_bloc/acs_bloc.dart b/lib/features/devices/bloc/acs_bloc/acs_bloc.dart index b88cf3b..792165f 100644 --- a/lib/features/devices/bloc/acs_bloc/acs_bloc.dart +++ b/lib/features/devices/bloc/acs_bloc/acs_bloc.dart @@ -71,7 +71,7 @@ class ACsBloc extends Bloc { deviceStatus = AcStatusModel.fromJson(response['productUuid'], statusModelList); emit(GetAcStatusState(acStatusModel: deviceStatus)); Future.delayed(const Duration(milliseconds: 500)); - // _listenToChanges(); + _listenToChanges(acId); } } catch (e) { emit(AcsFailedState(errorMessage: e.toString())); @@ -79,25 +79,38 @@ class ACsBloc extends Bloc { } } - _listenToChanges() { + StreamSubscription? _streamSubscription; + + void _listenToChanges(acId) { try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$acId'); + _streamSubscription?.cancel(); + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$acId'); Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) { - Map usersMap = event.snapshot.value as Map; + _streamSubscription = 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 = + AcStatusModel.fromJson(usersMap['productUuid'], statusList); - deviceStatus = AcStatusModel.fromJson(usersMap['productUuid'], statusList); add(AcUpdated()); }); } catch (_) {} } + @override + Future close() async { + _streamSubscription?.cancel(); + _streamSubscription = null; + return super.close(); + } + _onAcUpdated(AcUpdated event, Emitter emit) { emit(GetAcStatusState(acStatusModel: deviceStatus)); } @@ -109,13 +122,16 @@ class ACsBloc extends Bloc { HomeCubit.getInstance().selectedSpace?.id ?? '', 'AC'); for (int i = 0; i < devicesList.length; i++) { - var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); + _listenToChanges(devicesList[i].uuid); + var response = + await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); List statusModelList = []; for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); } deviceStatusList.add(AcStatusModel.fromJson(devicesList[i].uuid ?? '', statusModelList)); } + _setAllAcsTempsAndSwitches(); } diff --git a/lib/features/devices/bloc/ceiling_bloc/ceiling_sensor_bloc.dart b/lib/features/devices/bloc/ceiling_bloc/ceiling_sensor_bloc.dart index d8a463c..7b1628d 100644 --- a/lib/features/devices/bloc/ceiling_bloc/ceiling_sensor_bloc.dart +++ b/lib/features/devices/bloc/ceiling_bloc/ceiling_sensor_bloc.dart @@ -1,4 +1,4 @@ -import 'dart:convert'; +import 'dart:async'; import 'package:dio/dio.dart'; import 'package:firebase_database/firebase_database.dart'; @@ -35,35 +35,49 @@ class CeilingSensorBloc extends Bloc { } deviceStatus = CeilingSensorModel.fromJson(statusModelList); emit(UpdateState(ceilingSensorModel: deviceStatus)); - // _listenToChanges(); + _listenToChanges(); } catch (e) { emit(FailedState(error: e.toString())); return; } } - _listenToChanges() { + StreamSubscription? _streamSubscription; + Timer? _timer; + + void _listenToChanges() { try { + _streamSubscription?.cancel(); DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) { + _streamSubscription = stream.listen((DatabaseEvent event) async { + if (_timer != null) { + await Future.delayed(const Duration(seconds: 2)); + } Map usersMap = event.snapshot.value as Map; List statusList = []; - usersMap['status'].forEach((element) { statusList .add(StatusModel(code: element['code'], value: element['value'])); }); - deviceStatus = CeilingSensorModel.fromJson(statusList); - add(CeilingSensorUpdated()); + if (!isClosed) { + add(CeilingSensorUpdated()); + } }); } catch (_) {} } + @override + Future close() async { + _streamSubscription?.cancel(); + _streamSubscription = null; + return super.close(); + } + _onCeilingSensorUpdated( CeilingSensorUpdated event, Emitter emit) { emit(UpdateState(ceilingSensorModel: deviceStatus)); diff --git a/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart b/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart index 3cff103..bc6620e 100644 --- a/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart +++ b/lib/features/devices/bloc/curtain_bloc/curtain_bloc.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/curtain_bloc/curtain_event.dart'; @@ -169,7 +170,7 @@ class CurtainBloc extends Bloc { openPercentage = double.tryParse(statusModelList[1].value.toString())!; curtainWidth = 270 - (openPercentage / 100) * curtainOpeningSpace; blindHeight = 310 - (openPercentage / 100) * blindOpeningSpace; - + // _listenToChanges(); emit(CurtainsOpening( curtainWidth: curtainWidth, blindHeight: blindHeight, @@ -180,6 +181,38 @@ class CurtainBloc extends Bloc { return; } } + // Real-time Database + // StreamSubscription? _streamSubscription; + // Timer? _timer; + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$curtainId'); + // Stream stream = ref.onValue; + + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // deviceStatus = CurtainModel.fromJson(statusList); + // if (!isClosed) {} + // }); + // } catch (_) {} + // } + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } List groupList = []; bool allSwitchesOn = true; diff --git a/lib/features/devices/bloc/devices_cubit.dart b/lib/features/devices/bloc/devices_cubit.dart index 888b941..1053235 100644 --- a/lib/features/devices/bloc/devices_cubit.dart +++ b/lib/features/devices/bloc/devices_cubit.dart @@ -1,6 +1,9 @@ // ignore_for_file: constant_identifier_names, unused_import +import 'dart:async'; + import 'package:dio/dio.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; @@ -63,6 +66,43 @@ class DevicesCubit extends Cubit { } } + Timer? _timer; + + final Map> _deviceSubscriptions = + {}; + + void _listenToChanges(deviceId) { + try { + if (_deviceSubscriptions.containsKey(deviceId)) { + _deviceSubscriptions[deviceId]?.cancel(); + _deviceSubscriptions.remove(deviceId); + } + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); + Stream stream = ref.onValue; + final subscription = stream.listen((DatabaseEvent event) async { + if (_timer != null) { + await Future.delayed(const Duration(seconds: 2)); + } + Map usersMap = + event.snapshot.value as Map; + //print('object-----${usersMap['status']}'); + List statusList = []; + usersMap['status'].forEach((element) { + statusList + .add(StatusModel(code: element['code'], value: element['value'])); + }); + emitSafe(GetDevicesLoading()); + final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceId); + if (deviceIndex != -1) { + allDevices[deviceIndex].status = statusList; + } + emitSafe(GetDevicesSuccess(allDevices)); + }); + _deviceSubscriptions[deviceId] = subscription; + } catch (_) {} + } + static DevicesCubit get(context) => BlocProvider.of(context); List? allCategories; @@ -422,6 +462,11 @@ class DevicesCubit extends Cubit { spaceUuid: unit.id, projectId: project?.uuid ?? TempConst.projectIdDev); allDevices = devices; + for (var deviceId in allDevices) { + if (deviceId.type == "3G" || deviceId.type == "AC") { + _listenToChanges(deviceId.uuid); + } + } emitSafe(GetDevicesSuccess(allDevices)); } catch (e) { emitSafe(GetDevicesError(e.toString())); @@ -480,25 +525,35 @@ class DevicesCubit extends Cubit { } final device = allDevices[deviceIndex]; final switches = ['switch_1', 'switch_2', 'switch_3']; + final anySwitchOff = device.status.any( + (s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false), + ); + final targetState = anySwitchOff ? true : false; + for (final switchCode in switches) { final statusIndex = device.status.indexWhere((s) => s.code == switchCode); if (statusIndex != -1) { - final toggledValue = control.value; + final currentValue = device.status[statusIndex].value ?? false; + + if (!targetState && !currentValue) { + continue; + } final controlRequest = DeviceControlModel( - code: switchCode, value: toggledValue, deviceId: deviceUuid); + code: switchCode, value: targetState, deviceId: deviceUuid); final response = await DevicesAPI.controlDevice(controlRequest, deviceUuid); if (response['success'] != true) { throw Exception('Failed to toggle $switchCode'); } - device.status[statusIndex].value = toggledValue; + + device.status[statusIndex].value = targetState; } } - final anySwitchOff = device.status.any( - (s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false), + device.toggleStatus = device.status.every( + (s) => (s.code?.startsWith('switch_') ?? false) && (s.value == true), ); - device.toggleStatus = !anySwitchOff; + allDevices[deviceIndex] = device; emit(DeviceControlSuccess(code: control.code)); } catch (failure) { @@ -506,6 +561,7 @@ class DevicesCubit extends Cubit { } } + Future towGangToggle( DeviceControlModel control, String deviceUuid) async { emit(SwitchControlLoading(code: control.code)); diff --git a/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart b/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart index 15c7d76..20f2758 100644 --- a/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart +++ b/lib/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart'; import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart'; @@ -21,13 +20,14 @@ class DoorSensorBloc extends Bloc { on(_toggleClosingReminder); on(_toggleDoorAlarm); } - Timer? _timer; bool lowBattery = false; bool closingReminder = false; bool doorAlarm = false; - DoorSensorModel deviceStatus = DoorSensorModel(doorContactState: false, batteryPercentage: 0); + DoorSensorModel deviceStatus = + DoorSensorModel(doorContactState: false, batteryPercentage: 0); - void _fetchStatus(DoorSensorInitial event, Emitter emit) async { + void _fetchStatus( + DoorSensorInitial event, Emitter emit) async { emit(DoorSensorLoadingState()); try { var response = await DevicesAPI.getDeviceStatus(DSId); @@ -48,7 +48,8 @@ class DoorSensorBloc extends Bloc { } // Toggle functions for each switch - void _toggleLowBattery(ToggleLowBatteryEvent event, Emitter emit) async { + void _toggleLowBattery( + ToggleLowBatteryEvent event, Emitter emit) async { emit(LoadingNewSate(doorSensor: deviceStatus)); try { lowBattery = event.isLowBatteryEnabled; @@ -89,7 +90,8 @@ class DoorSensorBloc extends Bloc { } } - void _toggleDoorAlarm(ToggleDoorAlarmEvent event, Emitter emit) async { + void _toggleDoorAlarm( + ToggleDoorAlarmEvent event, Emitter emit) async { emit(LoadingNewSate(doorSensor: deviceStatus)); try { doorAlarm = event.isDoorAlarmEnabled; @@ -108,9 +110,11 @@ class DoorSensorBloc extends Bloc { } } - DeviceReport recordGroups = DeviceReport(startTime: '0', endTime: '0', data: []); + DeviceReport recordGroups = + DeviceReport(startTime: '0', endTime: '0', data: []); - Future fetchLogsForLastMonth(ReportLogsInitial event, Emitter emit) async { + Future fetchLogsForLastMonth( + ReportLogsInitial event, Emitter emit) async { DateTime now = DateTime.now(); DateTime lastMonth = DateTime(now.year, now.month - 1, now.day); @@ -132,30 +136,41 @@ class DoorSensorBloc extends Bloc { String errorMessage = errorData['message']; } } + // real-time database + // Timer? _timer; + // StreamSubscription? _streamSubscription; + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$DSId'); + // Stream stream = ref.onValue; - _listenToChanges() { - try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$DSId'); - Stream stream = ref.onValue; + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // deviceStatus = DoorSensorModel.fromJson(statusList); + // if (!isClosed) { + // add( + // DoorSensorSwitch(switchD: deviceStatus.doorContactState), + // ); + // } + // }); + // } catch (_) {} + // } - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = event.snapshot.value as Map; - List statusList = []; - - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: true)); - }); - - deviceStatus = DoorSensorModel.fromJson(statusList); - if (!isClosed) { - add( - DoorSensorSwitch(switchD: deviceStatus.doorContactState), - ); - } - }); - } catch (_) {} - } + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } } diff --git a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart index 7407467..7cb0a2a 100644 --- a/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart +++ b/lib/features/devices/bloc/four_scene_bloc/four_scene_bloc.dart @@ -233,6 +233,7 @@ class FourSceneBloc extends Bloc { deviceStatus = FourSceneModelState.fromJson( statusModelList, ); + // _listenToChanges(); add(const FourSceneSwitchInitial()); } catch (e) { emit(FourSceneFailedState(errorMessage: e.toString())); @@ -332,4 +333,33 @@ class FourSceneBloc extends Bloc { }).toList(); emit(SearchResultsState()); } + // Real-time database + // Timer? _timer; + // _listenToChanges() { + // try { + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$fourSceneId'); + // Stream stream = ref.onValue; + + // stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + + // usersMap['status'].forEach((element) { + // statusList.add(StatusModel(code: element['code'], value: true)); + // }); + + // deviceStatus = FourSceneModelState.fromJson(statusList); + // // if (!isClosed) { + // // add( + // // DoorSensorSwitch(switchD: deviceStatus.doorContactState), + // // ); + // // } + // }); + // } catch (_) {} + // } } diff --git a/lib/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart b/lib/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart index 43dcda4..b36e634 100644 --- a/lib/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart +++ b/lib/features/devices/bloc/garage_door_bloc/garage_door_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/garage_door_bloc/garage_door_event.dart'; @@ -42,7 +41,6 @@ class GarageDoorBloc extends Bloc { on(_changeFirstWizardSwitch); on(_toggleAlarmEvent); on(deleteSchedule); - //_toggleAlarmEvent } void _onClose(OnClose event, Emitter emit) { _timer?.cancel(); @@ -180,32 +178,40 @@ class GarageDoorBloc extends Bloc { } } - _listenToChanges() { - try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$GDId'); - Stream stream = ref.onValue; + // Real-time db + // StreamSubscription? _streamSubscription; + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$GDId'); + // Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = - event.snapshot.value as Map; - List statusList = []; - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: true)); - }); + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // deviceStatus = GarageDoorModel.fromJson(statusList); + // // if (!isClosed) { + // // add(ToggleSelectedEvent()); + // // } + // }); + // } catch (_) {} + // } - deviceStatus = GarageDoorModel.fromJson(statusList); - if (!isClosed) { - // add( - // DoorSensorSwitch(switchD: deviceStatus.doorContactState), - // ); - } - }); - } catch (_) {} - } + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } List> days = [ {"day": "Sun", "key": "Sun"}, diff --git a/lib/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart b/lib/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart index 9e7161d..c5ff33d 100644 --- a/lib/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart +++ b/lib/features/devices/bloc/one_gang_bloc/one_gang_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/one_gang_bloc/one_gang_state.dart'; @@ -26,7 +25,8 @@ class OneGangBloc extends Bloc { bool oneGangGroup = false; List devicesList = []; - OneGangBloc({required this.oneGangId, required this.switchCode}) : super(InitialState()) { + OneGangBloc({required this.oneGangId, required this.switchCode}) + : super(InitialState()) { on(_fetchOneGangStatus); on(_oneGangUpdated); on(_changeFirstSwitch); @@ -49,7 +49,8 @@ class OneGangBloc extends Bloc { on(_groupAllOff); } - void _fetchOneGangStatus(InitialEvent event, Emitter emit) async { + void _fetchOneGangStatus( + InitialEvent event, Emitter emit) async { emit(LoadingInitialState()); try { var response = await DevicesAPI.getDeviceStatus(oneGangId); @@ -65,36 +66,47 @@ class OneGangBloc extends Bloc { return; } } + // Real-time db + // StreamSubscription? _streamSubscription; + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$oneGangId'); + // Stream stream = ref.onValue; - _listenToChanges() { - try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneGangId'); - Stream stream = ref.onValue; + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // deviceStatus = OneGangModel.fromJson(statusList); + // if (!isClosed) { + // add(OneGangUpdated()); + // } + // }); + // } catch (_) {} + // } - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = event.snapshot.value as Map; - List statusList = []; - - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); - }); - - deviceStatus = OneGangModel.fromJson(statusList); - if (!isClosed) { - add(OneGangUpdated()); - } - }); - } catch (_) {} - } + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } _oneGangUpdated(OneGangUpdated event, Emitter emit) { emit(UpdateState(oneGangModel: deviceStatus)); } - void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter emit) async { + void _changeFirstSwitch( + ChangeFirstSwitchStatusEvent event, Emitter emit) async { emit(LoadingNewSate(oneGangModel: deviceStatus)); try { deviceStatus.firstSwitch = !event.value; @@ -119,17 +131,20 @@ class OneGangBloc extends Bloc { } } - void _changeSliding(ChangeSlidingSegment event, Emitter emit) async { + void _changeSliding( + ChangeSlidingSegment event, Emitter emit) async { emit(ChangeSlidingSegmentState(value: event.value)); } - void _setCounterValue(SetCounterValue event, Emitter emit) async { + void _setCounterValue( + SetCounterValue event, Emitter emit) async { emit(LoadingNewSate(oneGangModel: deviceStatus)); int seconds = 0; try { seconds = event.duration.inSeconds; final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: oneGangId, code: event.deviceCode, value: seconds), + DeviceControlModel( + deviceId: oneGangId, code: event.deviceCode, value: seconds), oneGangId); if (response['success'] ?? false) { @@ -152,7 +167,8 @@ class OneGangBloc extends Bloc { } } - void _getCounterValue(GetCounterEvent event, Emitter emit) async { + void _getCounterValue( + GetCounterEvent event, Emitter emit) async { emit(LoadingInitialState()); try { var response = await DevicesAPI.getDeviceStatus(oneGangId); @@ -241,7 +257,8 @@ class OneGangBloc extends Bloc { deviceId: oneGangId, ); List jsonData = response; - listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); + listSchedule = + jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); emit(InitialState()); } on DioException catch (e) { final errorData = e.response!.data; @@ -252,12 +269,13 @@ class OneGangBloc extends Bloc { int? getTimeStampWithoutSeconds(DateTime? dateTime) { if (dateTime == null) return null; - DateTime dateTimeWithoutSeconds = - DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute); + DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, + dateTime.day, dateTime.hour, dateTime.minute); return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; } - Future toggleChange(ToggleScheduleEvent event, Emitter emit) async { + Future toggleChange( + ToggleScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.changeSchedule( @@ -276,7 +294,8 @@ class OneGangBloc extends Bloc { } } - Future deleteSchedule(DeleteScheduleEvent event, Emitter emit) async { + Future deleteSchedule( + DeleteScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.deleteSchedule( @@ -296,7 +315,8 @@ class OneGangBloc extends Bloc { } } - void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter emit) { + void toggleCreateSchedule( + ToggleCreateScheduleEvent event, Emitter emit) { emit(LoadingInitialState()); createSchedule = !createSchedule; selectedDays.clear(); @@ -325,7 +345,8 @@ class OneGangBloc extends Bloc { int selectedTabIndex = 0; - void toggleSelectedIndex(ToggleSelectedEvent event, Emitter emit) { + void toggleSelectedIndex( + ToggleSelectedEvent event, Emitter emit) { emit(LoadingInitialState()); selectedTabIndex = event.index; emit(ChangeSlidingSegmentState(value: selectedTabIndex)); @@ -334,7 +355,8 @@ class OneGangBloc extends Bloc { List groupOneGangList = []; bool allSwitchesOn = true; - void _fetchOneGangWizardStatus(InitialWizardEvent event, Emitter emit) async { + void _fetchOneGangWizardStatus( + InitialWizardEvent event, Emitter emit) async { emit(LoadingInitialState()); try { devicesList = []; @@ -344,7 +366,8 @@ class OneGangBloc extends Bloc { HomeCubit.getInstance().selectedSpace?.id ?? '', '1G'); for (int i = 0; i < devicesList.length; i++) { - var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); + var response = + await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); List statusModelList = []; for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); @@ -365,15 +388,16 @@ class OneGangBloc extends Bloc { return true; }); } - emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesOn)); + emit(UpdateGroupState( + oneGangList: groupOneGangList, allSwitches: allSwitchesOn)); } catch (e) { emit(FailedState(error: e.toString())); return; } } - void _changeFirstWizardSwitch( - ChangeFirstWizardSwitchStatusEvent event, Emitter emit) async { + void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event, + Emitter emit) async { emit(LoadingNewSate(oneGangModel: deviceStatus)); try { bool allSwitchesValue = true; @@ -386,7 +410,8 @@ class OneGangBloc extends Bloc { } }); - emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + oneGangList: groupOneGangList, allSwitches: allSwitchesValue)); final response = await DevicesAPI.deviceBatchController( code: 'switch_1', @@ -414,7 +439,8 @@ class OneGangBloc extends Bloc { emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: true)); // Get a list of all device IDs - List allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList(); + List allDeviceIds = + groupOneGangList.map((device) => device.deviceId).toList(); // First call for switch_1 final response = await DevicesAPI.deviceBatchController( @@ -446,7 +472,8 @@ class OneGangBloc extends Bloc { emit(UpdateGroupState(oneGangList: groupOneGangList, allSwitches: false)); // Get a list of all device IDs - List allDeviceIds = groupOneGangList.map((device) => device.deviceId).toList(); + List allDeviceIds = + groupOneGangList.map((device) => device.deviceId).toList(); // First call for switch_1 final response = await DevicesAPI.deviceBatchController( diff --git a/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart b/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart index 37e016f..d18a248 100644 --- a/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart +++ b/lib/features/devices/bloc/one_touch_bloc/one_touch_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; @@ -30,7 +29,8 @@ class OneTouchBloc extends Bloc { bool oneTouchGroup = false; List devicesList = []; - OneTouchBloc({required this.oneTouchId, required this.switchCode}) : super(InitialState()) { + OneTouchBloc({required this.oneTouchId, required this.switchCode}) + : super(InitialState()) { on(_fetchOneTouchStatus); on(_oneTouchUpdated); on(_changeFirstSwitch); @@ -53,7 +53,8 @@ class OneTouchBloc extends Bloc { on(_changeStatus); } - void _fetchOneTouchStatus(InitialEvent event, Emitter emit) async { + void _fetchOneTouchStatus( + InitialEvent event, Emitter emit) async { emit(LoadingInitialState()); try { var response = await DevicesAPI.getDeviceStatus(oneTouchId); @@ -63,42 +64,43 @@ class OneTouchBloc extends Bloc { } deviceStatus = OneTouchModel.fromJson(statusModelList); emit(UpdateState(oneTouchModel: deviceStatus)); - // _listenToChanges(); + // _listenToChanges(); } catch (e) { emit(FailedState(error: e.toString())); return; } } + // Real-time db + // _listenToChanges() { + // try { + // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneTouchId'); + // Stream stream = ref.onValue; - _listenToChanges() { - try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$oneTouchId'); - Stream stream = ref.onValue; + // stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = event.snapshot.value as Map; + // List statusList = []; - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = event.snapshot.value as Map; - List statusList = []; + // usersMap['status'].forEach((element) { + // statusList.add(StatusModel(code: element['code'], value: element['value'])); + // }); - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); - }); - - deviceStatus = OneTouchModel.fromJson(statusList); - if (!isClosed) { - add(OneTouchUpdated()); - } - }); - } catch (_) {} - } + // deviceStatus = OneTouchModel.fromJson(statusList); + // if (!isClosed) { + // add(OneTouchUpdated()); + // } + // }); + // } catch (_) {} + // } _oneTouchUpdated(OneTouchUpdated event, Emitter emit) { emit(UpdateState(oneTouchModel: deviceStatus)); } - void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter emit) async { + void _changeFirstSwitch( + ChangeFirstSwitchStatusEvent event, Emitter emit) async { emit(LoadingNewSate(oneTouchModel: deviceStatus)); try { deviceStatus.firstSwitch = !event.value; @@ -123,17 +125,20 @@ class OneTouchBloc extends Bloc { } } - void _changeSliding(ChangeSlidingSegment event, Emitter emit) async { + void _changeSliding( + ChangeSlidingSegment event, Emitter emit) async { emit(ChangeSlidingSegmentState(value: event.value)); } - void _setCounterValue(SetCounterValue event, Emitter emit) async { + void _setCounterValue( + SetCounterValue event, Emitter emit) async { emit(LoadingNewSate(oneTouchModel: deviceStatus)); int seconds = 0; try { seconds = event.duration.inSeconds; final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: oneTouchId, code: event.deviceCode, value: seconds), + DeviceControlModel( + deviceId: oneTouchId, code: event.deviceCode, value: seconds), oneTouchId); if (response['success'] ?? false) { @@ -156,7 +161,8 @@ class OneTouchBloc extends Bloc { } } - void _getCounterValue(GetCounterEvent event, Emitter emit) async { + void _getCounterValue( + GetCounterEvent event, Emitter emit) async { emit(LoadingInitialState()); try { var response = await DevicesAPI.getDeviceStatus(oneTouchId); @@ -245,7 +251,8 @@ class OneTouchBloc extends Bloc { deviceId: oneTouchId, ); List jsonData = response; - listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); + listSchedule = + jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); emit(InitialState()); } on DioException catch (e) { final errorData = e.response!.data; @@ -256,12 +263,13 @@ class OneTouchBloc extends Bloc { int? getTimeStampWithoutSeconds(DateTime? dateTime) { if (dateTime == null) return null; - DateTime dateTimeWithoutSeconds = - DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute); + DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, + dateTime.day, dateTime.hour, dateTime.minute); return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; } - Future toggleChange(ToggleScheduleEvent event, Emitter emit) async { + Future toggleChange( + ToggleScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.changeSchedule( @@ -280,7 +288,8 @@ class OneTouchBloc extends Bloc { } } - Future deleteSchedule(DeleteScheduleEvent event, Emitter emit) async { + Future deleteSchedule( + DeleteScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.deleteSchedule( @@ -300,7 +309,8 @@ class OneTouchBloc extends Bloc { } } - void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter emit) { + void toggleCreateSchedule( + ToggleCreateScheduleEvent event, Emitter emit) { emit(LoadingInitialState()); createSchedule = !createSchedule; selectedDays.clear(); @@ -329,7 +339,8 @@ class OneTouchBloc extends Bloc { int selectedTabIndex = 0; - void toggleSelectedIndex(ToggleSelectedEvent event, Emitter emit) { + void toggleSelectedIndex( + ToggleSelectedEvent event, Emitter emit) { emit(LoadingInitialState()); selectedTabIndex = event.index; emit(ChangeSlidingSegmentState(value: selectedTabIndex)); @@ -338,7 +349,8 @@ class OneTouchBloc extends Bloc { List groupOneTouchList = []; bool allSwitchesOn = true; - void _fetchOneTouchWizardStatus(InitialWizardEvent event, Emitter emit) async { + void _fetchOneTouchWizardStatus( + InitialWizardEvent event, Emitter emit) async { emit(LoadingInitialState()); try { devicesList = []; @@ -348,7 +360,8 @@ class OneTouchBloc extends Bloc { HomeCubit.getInstance().selectedSpace?.id ?? '', '1GT'); for (int i = 0; i < devicesList.length; i++) { - var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); + var response = + await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); List statusModelList = []; for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); @@ -369,15 +382,16 @@ class OneTouchBloc extends Bloc { return true; }); } - emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesOn)); + emit(UpdateGroupState( + oneTouchList: groupOneTouchList, allSwitches: allSwitchesOn)); } catch (e) { emit(FailedState(error: e.toString())); return; } } - void _changeFirstWizardSwitch( - ChangeFirstWizardSwitchStatusEvent event, Emitter emit) async { + void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event, + Emitter emit) async { emit(LoadingNewSate(oneTouchModel: deviceStatus)); try { bool allSwitchesValue = true; @@ -395,7 +409,8 @@ class OneTouchBloc extends Bloc { value: !event.value, ); - emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + oneTouchList: groupOneTouchList, allSwitches: allSwitchesValue)); if (response['success']) { add(InitialEvent(groupScreen: oneTouchGroup)); } @@ -413,10 +428,12 @@ class OneTouchBloc extends Bloc { } // Emit the state with updated values - emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: true)); + emit( + UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: true)); // Get a list of all device IDs - List allDeviceIds = groupOneTouchList.map((device) => device.deviceId).toList(); + List allDeviceIds = + groupOneTouchList.map((device) => device.deviceId).toList(); // First call for switch_1 final response1 = await DevicesAPI.deviceBatchController( @@ -445,10 +462,12 @@ class OneTouchBloc extends Bloc { } // Emit the state with updated values - emit(UpdateGroupState(oneTouchList: groupOneTouchList, allSwitches: false)); + emit(UpdateGroupState( + oneTouchList: groupOneTouchList, allSwitches: false)); // Get a list of all device IDs - List allDeviceIds = groupOneTouchList.map((device) => device.deviceId).toList(); + List allDeviceIds = + groupOneTouchList.map((device) => device.deviceId).toList(); // First call for switch_1 final response1 = await DevicesAPI.deviceBatchController( @@ -472,7 +491,8 @@ class OneTouchBloc extends Bloc { String statusSelected = ''; String optionSelected = ''; - Future _changeStatus(ChangeStatusEvent event, Emitter emit) async { + Future _changeStatus( + ChangeStatusEvent event, Emitter emit) async { try { emit(LoadingInitialState()); @@ -497,7 +517,10 @@ class OneTouchBloc extends Bloc { final selectedControl = controlMap[optionSelected]?[statusSelected]; if (selectedControl != null) { await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: oneTouchId, code: optionSelected, value: selectedControl), + DeviceControlModel( + deviceId: oneTouchId, + code: optionSelected, + value: selectedControl), oneTouchId, ); } else { diff --git a/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart b/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart index 7f1a606..d749fb3 100644 --- a/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart +++ b/lib/features/devices/bloc/smart_door_bloc/smart_door_bloc.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:math'; import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; @@ -37,7 +38,8 @@ class SmartDoorBloc extends Bloc { on(selectTimeOfLinePassword); on(selectTimeOnlinePassword); on(deletePassword); - on(generateAndSavePasswordTimeLimited); + on( + generateAndSavePasswordTimeLimited); on(generateAndSavePasswordOneTime); on(toggleDaySelection); on(_renamePassword); @@ -59,7 +61,8 @@ class SmartDoorBloc extends Bloc { List? oneTimePasswords = []; List? timeLimitPasswords = []; - Future generate7DigitNumber(GeneratePasswordEvent event, Emitter emit) async { + Future generate7DigitNumber( + GeneratePasswordEvent event, Emitter emit) async { emit(LoadingInitialState()); passwordController.clear(); Random random = Random(); @@ -71,7 +74,8 @@ class SmartDoorBloc extends Bloc { } Future generateAndSavePasswordOneTime( - GenerateAndSavePasswordOneTimeEvent event, Emitter emit) async { + GenerateAndSavePasswordOneTimeEvent event, + Emitter emit) async { try { if (isSavingPassword) return; isSavingPassword = true; @@ -92,7 +96,8 @@ class SmartDoorBloc extends Bloc { } } - void _fetchSmartDoorStatus(InitialEvent event, Emitter emit) async { + void _fetchSmartDoorStatus( + InitialEvent event, Emitter emit) async { try { emit(LoadingInitialState()); var response = await DevicesAPI.getDeviceStatus(deviceId); @@ -102,42 +107,63 @@ class SmartDoorBloc extends Bloc { } deviceStatus = SmartDoorModel.fromJson(statusModelList); emit(UpdateState(smartDoorModel: deviceStatus)); - // _listenToChanges(); + _listenToChanges(); } catch (e) { emit(FailedState(errorMessage: e.toString())); return; } } - _listenToChanges() { + StreamSubscription? _streamSubscription; + Timer? _timer; + + void _listenToChanges() { try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + _streamSubscription?.cancel(); + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) { - Map usersMap = event.snapshot.value as Map; + _streamSubscription = stream.listen((DatabaseEvent event) async { + if (_timer != null) { + await Future.delayed(const Duration(seconds: 2)); + } + Map usersMap = + event.snapshot.value as Map; List statusList = []; - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); + statusList + .add(StatusModel(code: element['code'], value: element['value'])); }); - deviceStatus = SmartDoorModel.fromJson(statusList); - add(DoorLockUpdated()); + if (!isClosed) { + add(DoorLockUpdated()); + } }); } catch (_) {} } + @override + Future close() async { + _streamSubscription?.cancel(); + _streamSubscription = null; + return super.close(); + } + + _doorLockUpdated(DoorLockUpdated event, Emitter emit) { unlockRequest = deviceStatus.unlockRequest; emit(UpdateState(smartDoorModel: deviceStatus)); } - void _renamePassword(RenamePasswordEvent event, Emitter emit) async { + void _renamePassword( + RenamePasswordEvent event, Emitter emit) async { try { emit(LoadingInitialState()); await DevicesAPI.renamePass( - name: passwordNameController.text, doorLockUuid: deviceId, passwordId: passwordId); + name: passwordNameController.text, + doorLockUuid: deviceId, + passwordId: passwordId); add(InitialOneTimePassword()); add(InitialTimeLimitPassword()); emit(UpdateState(smartDoorModel: deviceStatus)); @@ -147,46 +173,58 @@ class SmartDoorBloc extends Bloc { } } - void getTemporaryPasswords(InitialPasswordsPage event, Emitter emit) async { + void getTemporaryPasswords( + InitialPasswordsPage event, Emitter emit) async { try { emit(LoadingInitialState()); var response = await DevicesAPI.getTemporaryPasswords( deviceId, ); if (response is List) { - temporaryPasswords = response.map((item) => TemporaryPassword.fromJson(item)).toList(); - } else if (response is Map && response.containsKey('data')) { temporaryPasswords = - (response['data'] as List).map((item) => TemporaryPassword.fromJson(item)).toList(); + response.map((item) => TemporaryPassword.fromJson(item)).toList(); + } else if (response is Map && response.containsKey('data')) { + temporaryPasswords = (response['data'] as List) + .map((item) => TemporaryPassword.fromJson(item)) + .toList(); } - emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!)); + emit(TemporaryPasswordsLoadedState( + temporaryPassword: temporaryPasswords!)); } catch (e) { emit(FailedState(errorMessage: e.toString())); } } - void getOneTimePasswords(InitialOneTimePassword event, Emitter emit) async { + void getOneTimePasswords( + InitialOneTimePassword event, Emitter emit) async { try { emit(LoadingInitialState()); var response = await DevicesAPI.getOneTimePasswords(deviceId); if (response is List) { - oneTimePasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList(); + oneTimePasswords = response + .map((item) => OfflinePasswordModel.fromJson(item)) + .toList(); } - emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!)); + emit(TemporaryPasswordsLoadedState( + temporaryPassword: temporaryPasswords!)); } catch (e) { emit(FailedState(errorMessage: e.toString())); } } - void getTimeLimitPasswords(InitialTimeLimitPassword event, Emitter emit) async { + void getTimeLimitPasswords( + InitialTimeLimitPassword event, Emitter emit) async { try { emit(LoadingInitialState()); var response = await DevicesAPI.getTimeLimitPasswords(deviceId); if (response is List) { - timeLimitPasswords = response.map((item) => OfflinePasswordModel.fromJson(item)).toList(); + timeLimitPasswords = response + .map((item) => OfflinePasswordModel.fromJson(item)) + .toList(); } - emit(TemporaryPasswordsLoadedState(temporaryPassword: temporaryPasswords!)); + emit(TemporaryPasswordsLoadedState( + temporaryPassword: temporaryPasswords!)); } catch (e) { emit(FailedState(errorMessage: e.toString())); } @@ -207,7 +245,8 @@ class SmartDoorBloc extends Bloc { return repeat; } - bool setStartEndTime(SetStartEndTimeEvent event, Emitter emit) { + bool setStartEndTime( + SetStartEndTimeEvent event, Emitter emit) { emit(LoadingInitialState()); isStartEndTime = event.val; emit(IsStartEndState(isStartEndTime: isStartEndTime)); @@ -230,7 +269,8 @@ class SmartDoorBloc extends Bloc { emit(UpdateState(smartDoorModel: deviceStatus)); } - Future selectTimeOfLinePassword(SelectTimeEvent event, Emitter emit) async { + Future selectTimeOfLinePassword( + SelectTimeEvent event, Emitter emit) async { emit(ChangeTimeState()); final DateTime? picked = await showDatePicker( context: event.context, @@ -260,20 +300,27 @@ class SmartDoorBloc extends Bloc { ).millisecondsSinceEpoch ~/ 1000; // Divide by 1000 to remove milliseconds if (event.isEffective) { - if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) { - CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.'); + if (expirationTimeTimeStamp != null && + selectedTimestamp > expirationTimeTimeStamp!) { + CustomSnackBar.displaySnackBar( + 'Effective Time cannot be later than Expiration Time.'); } else { - effectiveTime = - selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds + effectiveTime = selectedDateTime + .toString() + .split('.') + .first; // Remove seconds and milliseconds effectiveTimeTimeStamp = selectedTimestamp; } } else { - if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) { + if (effectiveTimeTimeStamp != null && + selectedTimestamp < effectiveTimeTimeStamp!) { CustomSnackBar.displaySnackBar( 'Expiration Time cannot be earlier than Effective Time.'); } else { - expirationTime = - selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds + expirationTime = selectedDateTime + .toString() + .split('.') + .first; // Remove seconds and milliseconds expirationTimeTimeStamp = selectedTimestamp; } } @@ -329,20 +376,27 @@ class SmartDoorBloc extends Bloc { ).millisecondsSinceEpoch ~/ 1000; // Divide by 1000 to remove milliseconds if (event.isEffective) { - if (expirationTimeTimeStamp != null && selectedTimestamp > expirationTimeTimeStamp!) { - CustomSnackBar.displaySnackBar('Effective Time cannot be later than Expiration Time.'); + if (expirationTimeTimeStamp != null && + selectedTimestamp > expirationTimeTimeStamp!) { + CustomSnackBar.displaySnackBar( + 'Effective Time cannot be later than Expiration Time.'); } else { - effectiveTime = - selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds + effectiveTime = selectedDateTime + .toString() + .split('.') + .first; // Remove seconds and milliseconds effectiveTimeTimeStamp = selectedTimestamp; } } else { - if (effectiveTimeTimeStamp != null && selectedTimestamp < effectiveTimeTimeStamp!) { + if (effectiveTimeTimeStamp != null && + selectedTimestamp < effectiveTimeTimeStamp!) { CustomSnackBar.displaySnackBar( 'Expiration Time cannot be earlier than Effective Time.'); } else { - expirationTime = - selectedDateTime.toString().split('.').first; // Remove seconds and milliseconds + expirationTime = selectedDateTime + .toString() + .split('.') + .first; // Remove seconds and milliseconds expirationTimeTimeStamp = selectedTimestamp; } } @@ -351,7 +405,8 @@ class SmartDoorBloc extends Bloc { } } - Future savePassword(SavePasswordEvent event, Emitter emit) async { + Future savePassword( + SavePasswordEvent event, Emitter emit) async { if (_validateInputs() || isSavingPassword) return; try { isSavingPassword = true; @@ -381,7 +436,8 @@ class SmartDoorBloc extends Bloc { } Future generateAndSavePasswordTimeLimited( - GenerateAndSavePasswordTimeLimitEvent event, Emitter emit) async { + GenerateAndSavePasswordTimeLimitEvent event, + Emitter emit) async { if (timeLimitValidate() || isSavingPassword) return; try { isSavingPassword = true; @@ -407,10 +463,12 @@ class SmartDoorBloc extends Bloc { } } - Future deletePassword(DeletePasswordEvent event, Emitter emit) async { + Future deletePassword( + DeletePasswordEvent event, Emitter emit) async { try { emit(LoadingInitialState()); - await DevicesAPI.deletePassword(deviceId: deviceId, passwordId: event.passwordId) + await DevicesAPI.deletePassword( + deviceId: deviceId, passwordId: event.passwordId) .then((value) async { add(InitialPasswordsPage()); }); @@ -445,7 +503,8 @@ class SmartDoorBloc extends Bloc { } if (repeat == true && (endTime == null || startTime == null)) { - CustomSnackBar.displaySnackBar('Start Time and End time and the days required '); + CustomSnackBar.displaySnackBar( + 'Start Time and End time and the days required '); return true; } return false; diff --git a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart index 0b0d028..8c7dc95 100644 --- a/lib/features/devices/bloc/sos_bloc/sos_bloc.dart +++ b/lib/features/devices/bloc/sos_bloc/sos_bloc.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'package:dio/dio.dart'; +import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; @@ -173,6 +174,7 @@ class SosBloc extends Bloc { ); emit(UpdateState(sensor: deviceStatus)); Future.delayed(const Duration(milliseconds: 500)); + // _listenToChanges(); } catch (e) { emit(SosFailedState(errorMessage: e.toString())); return; @@ -434,4 +436,39 @@ class SosBloc extends Bloc { emit(SosFailedState(errorMessage: e.toString())); } } + + + //real-time db + // StreamSubscription? _streamSubscription; + // Timer? _timer; + + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$sosId'); + // Stream stream = ref.onValue; + + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // deviceStatus = SosModel.fromJson(statusList); + // }); + // } catch (_) {} + // } + + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } } diff --git a/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart b/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart index 04f434c..ceeffd0 100644 --- a/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart +++ b/lib/features/devices/bloc/three_gang_bloc/three_gang_bloc.dart @@ -31,7 +31,8 @@ class ThreeGangBloc extends Bloc { List groupThreeGangList = []; bool allSwitchesOn = true; - ThreeGangBloc({required this.threeGangId, required this.switchCode}) : super(InitialState()) { + ThreeGangBloc({required this.threeGangId, required this.switchCode}) + : super(InitialState()) { on(_fetchThreeGangStatus); on(_threeGangUpdated); on(_changeFirstSwitch); @@ -57,7 +58,8 @@ class ThreeGangBloc extends Bloc { on(toggleCreateSchedule); } - void _fetchThreeGangStatus(InitialEvent event, Emitter emit) async { + void _fetchThreeGangStatus( + InitialEvent event, Emitter emit) async { emit(LoadingInitialState()); try { threeGangGroup = event.groupScreen; @@ -69,7 +71,8 @@ class ThreeGangBloc extends Bloc { HomeCubit.getInstance().selectedSpace?.id ?? '', '3G'); for (int i = 0; i < devicesList.length; i++) { - var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); + var response = + await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); List statusModelList = []; for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); @@ -86,13 +89,16 @@ class ThreeGangBloc extends Bloc { if (groupThreeGangList.isNotEmpty) { groupThreeGangList.firstWhere((element) { - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesOn = false; } return true; }); } - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesOn)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesOn)); } else { var response = await DevicesAPI.getDeviceStatus(threeGangId); List statusModelList = []; @@ -101,7 +107,7 @@ class ThreeGangBloc extends Bloc { } deviceStatus = ThreeGangModel.fromJson(statusModelList); emit(UpdateState(threeGangModel: deviceStatus)); - // _listenToChanges(); + _listenToChanges(); } } catch (e) { emit(FailedState(error: e.toString())); @@ -109,22 +115,26 @@ class ThreeGangBloc extends Bloc { } } - _listenToChanges() { + StreamSubscription? _streamSubscription; + + void _listenToChanges() { try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeGangId'); + _streamSubscription?.cancel(); + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$threeGangId'); Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) async { + _streamSubscription = stream.listen((DatabaseEvent event) async { if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); + await Future.delayed(const Duration(seconds: 1)); } - Map usersMap = event.snapshot.value as Map; + Map usersMap = + event.snapshot.value as Map; List statusList = []; - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); + statusList + .add(StatusModel(code: element['code'], value: element['value'])); }); - deviceStatus = ThreeGangModel.fromJson(statusList); if (!isClosed) { add(ThreeGangUpdated()); @@ -133,11 +143,19 @@ class ThreeGangBloc extends Bloc { } catch (_) {} } + @override + Future close() async { + _streamSubscription?.cancel(); + _streamSubscription = null; + return super.close(); + } + _threeGangUpdated(ThreeGangUpdated event, Emitter emit) { emit(UpdateState(threeGangModel: deviceStatus)); } - void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter emit) async { + void _changeFirstSwitch( + ChangeFirstSwitchStatusEvent event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); try { if (threeGangGroup) { @@ -146,11 +164,14 @@ class ThreeGangBloc extends Bloc { if (element.deviceId == event.deviceId) { element.firstSwitch = !event.value; } - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesValue = false; } }); - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); } else { deviceStatus.firstSwitch = !event.value; emit(UpdateState(threeGangModel: deviceStatus)); @@ -187,11 +208,14 @@ class ThreeGangBloc extends Bloc { if (element.deviceId == event.deviceId) { element.secondSwitch = !event.value; } - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesValue = false; } }); - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); } else { deviceStatus.secondSwitch = !event.value; emit(UpdateState(threeGangModel: deviceStatus)); @@ -217,7 +241,8 @@ class ThreeGangBloc extends Bloc { } } - void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter emit) async { + void _changeThirdSwitch( + ChangeThirdSwitchStatusEvent event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); try { if (threeGangGroup) { @@ -226,11 +251,14 @@ class ThreeGangBloc extends Bloc { if (element.deviceId == event.deviceId) { element.thirdSwitch = !event.value; } - if (!element.firstSwitch || !element.secondSwitch || !element.thirdSwitch) { + if (!element.firstSwitch || + !element.secondSwitch || + !element.thirdSwitch) { allSwitchesValue = false; } }); - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: allSwitchesValue)); } else { deviceStatus.thirdSwitch = !event.value; emit(UpdateState(threeGangModel: deviceStatus)); @@ -269,15 +297,21 @@ class ThreeGangBloc extends Bloc { final response = await Future.wait([ DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch), + deviceId: threeGangId, + code: 'switch_1', + value: deviceStatus.firstSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch), + deviceId: threeGangId, + code: 'switch_2', + value: deviceStatus.secondSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch), + deviceId: threeGangId, + code: 'switch_3', + value: deviceStatus.thirdSwitch), threeGangId), ]); @@ -303,15 +337,21 @@ class ThreeGangBloc extends Bloc { final response = await Future.wait([ DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_1', value: deviceStatus.firstSwitch), + deviceId: threeGangId, + code: 'switch_1', + value: deviceStatus.firstSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_2', value: deviceStatus.secondSwitch), + deviceId: threeGangId, + code: 'switch_2', + value: deviceStatus.secondSwitch), threeGangId), DevicesAPI.controlDevice( DeviceControlModel( - deviceId: threeGangId, code: 'switch_3', value: deviceStatus.thirdSwitch), + deviceId: threeGangId, + code: 'switch_3', + value: deviceStatus.thirdSwitch), threeGangId), ]); @@ -333,9 +373,11 @@ class ThreeGangBloc extends Bloc { groupThreeGangList[i].secondSwitch = true; groupThreeGangList[i].thirdSwitch = true; } - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: true)); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: true)); - List allDeviceIds = groupThreeGangList.map((device) => device.deviceId).toList(); + List allDeviceIds = + groupThreeGangList.map((device) => device.deviceId).toList(); final response1 = await DevicesAPI.deviceBatchController( code: 'switch_1', @@ -365,7 +407,8 @@ class ThreeGangBloc extends Bloc { } } - void _groupAllOff(GroupAllOffEvent event, Emitter emit) async { + void _groupAllOff( + GroupAllOffEvent event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); try { for (int i = 0; i < groupThreeGangList.length; i++) { @@ -373,8 +416,10 @@ class ThreeGangBloc extends Bloc { groupThreeGangList[i].secondSwitch = false; groupThreeGangList[i].thirdSwitch = false; } - emit(UpdateGroupState(threeGangList: groupThreeGangList, allSwitches: false)); - List allDeviceIds = groupThreeGangList.map((device) => device.deviceId).toList(); + emit(UpdateGroupState( + threeGangList: groupThreeGangList, allSwitches: false)); + List allDeviceIds = + groupThreeGangList.map((device) => device.deviceId).toList(); final response1 = await DevicesAPI.deviceBatchController( code: 'switch_1', @@ -404,17 +449,20 @@ class ThreeGangBloc extends Bloc { } } - void _changeSliding(ChangeSlidingSegment event, Emitter emit) async { + void _changeSliding( + ChangeSlidingSegment event, Emitter emit) async { emit(ChangeSlidingSegmentState(value: event.value)); } - void _setCounterValue(SetCounterValue event, Emitter emit) async { + void _setCounterValue( + SetCounterValue event, Emitter emit) async { emit(LoadingNewSate(threeGangModel: deviceStatus)); int seconds = 0; try { seconds = event.duration.inSeconds; final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: threeGangId, code: event.deviceCode, value: seconds), + DeviceControlModel( + deviceId: threeGangId, code: event.deviceCode, value: seconds), threeGangId); if (response['success'] ?? false) { @@ -441,7 +489,8 @@ class ThreeGangBloc extends Bloc { } } - void _getCounterValue(GetCounterEvent event, Emitter emit) async { + void _getCounterValue( + GetCounterEvent event, Emitter emit) async { emit(LoadingInitialState()); try { var response = await DevicesAPI.getDeviceStatus(threeGangId); @@ -551,7 +600,8 @@ class ThreeGangBloc extends Bloc { deviceId: threeGangId, ); List jsonData = response; - listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); + listSchedule = + jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); emit(InitialState()); } on DioException catch (e) { final errorData = e.response!.data; @@ -562,12 +612,13 @@ class ThreeGangBloc extends Bloc { int? getTimeStampWithoutSeconds(DateTime? dateTime) { if (dateTime == null) return null; - DateTime dateTimeWithoutSeconds = - DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute); + DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, + dateTime.day, dateTime.hour, dateTime.minute); return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; } - Future toggleChange(ToggleScheduleEvent event, Emitter emit) async { + Future toggleChange( + ToggleScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.changeSchedule( @@ -586,7 +637,8 @@ class ThreeGangBloc extends Bloc { } } - Future deleteSchedule(DeleteScheduleEvent event, Emitter emit) async { + Future deleteSchedule( + DeleteScheduleEvent event, Emitter emit) async { try { emit(LoadingInitialState()); final response = await DevicesAPI.deleteSchedule( @@ -606,13 +658,15 @@ class ThreeGangBloc extends Bloc { } } - void toggleSelectedIndex(ToggleSelectedEvent event, Emitter emit) { + void toggleSelectedIndex( + ToggleSelectedEvent event, Emitter emit) { emit(LoadingInitialState()); selectedTabIndex = event.index; emit(ChangeSlidingSegmentState(value: selectedTabIndex)); } - void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter emit) { + void toggleCreateSchedule( + ToggleCreateScheduleEvent event, Emitter emit) { emit(LoadingInitialState()); createSchedule = !createSchedule; selectedDays.clear(); diff --git a/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart b/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart index beec442..8b5af81 100644 --- a/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart +++ b/lib/features/devices/bloc/three_touch_bloc/three_touch_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/three_touch_bloc/three_touch_event.dart'; @@ -107,7 +106,7 @@ class ThreeTouchBloc extends Bloc { } deviceStatus = ThreeTouchModel.fromJson(statusModelList); emit(UpdateState(threeTouchModel: deviceStatus)); - // _listenToChanges(); + // _listenToChanges(); } } catch (e) { emit(FailedState(error: e.toString())); @@ -115,29 +114,29 @@ class ThreeTouchBloc extends Bloc { } } - _listenToChanges() { - try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeTouchId'); - Stream stream = ref.onValue; + // _listenToChanges() { + // try { + // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$threeTouchId'); + // Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = event.snapshot.value as Map; - List statusList = []; + // stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = event.snapshot.value as Map; + // List statusList = []; - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); - }); + // usersMap['status'].forEach((element) { + // statusList.add(StatusModel(code: element['code'], value: element['value'])); + // }); - deviceStatus = ThreeTouchModel.fromJson(statusList); - if (!isClosed) { - add(ThreeTouchUpdated()); - } - }); - } catch (_) {} - } + // deviceStatus = ThreeTouchModel.fromJson(statusList); + // if (!isClosed) { + // add(ThreeTouchUpdated()); + // } + // }); + // } catch (_) {} + // } _threeTouchUpdated(ThreeTouchUpdated event, Emitter emit) { emit(UpdateState(threeTouchModel: deviceStatus)); diff --git a/lib/features/devices/bloc/two_gang_bloc/two_gang_bloc.dart b/lib/features/devices/bloc/two_gang_bloc/two_gang_bloc.dart index 7906348..5435148 100644 --- a/lib/features/devices/bloc/two_gang_bloc/two_gang_bloc.dart +++ b/lib/features/devices/bloc/two_gang_bloc/two_gang_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/two_gang_bloc/two_gang_event.dart'; @@ -96,29 +95,29 @@ class TwoGangBloc extends Bloc { } } - _listenToChanges() { - try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoGangId'); - Stream stream = ref.onValue; + // _listenToChanges() { + // try { + // DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$twoGangId'); + // Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = event.snapshot.value as Map; - List statusList = []; + // stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = event.snapshot.value as Map; + // List statusList = []; - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); - }); + // usersMap['status'].forEach((element) { + // statusList.add(StatusModel(code: element['code'], value: element['value'])); + // }); - deviceStatus = TwoGangModel.fromJson(statusList); - if (!isClosed) { - add(TwoGangUpdated()); - } - }); - } catch (_) {} - } + // deviceStatus = TwoGangModel.fromJson(statusList); + // if (!isClosed) { + // add(TwoGangUpdated()); + // } + // }); + // } catch (_) {} + // } _twoGangUpdated(TwoGangUpdated event, Emitter emit) { emit(UpdateState(twoGangModel: deviceStatus)); diff --git a/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart b/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart index 56031c8..9a62a5e 100644 --- a/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart +++ b/lib/features/devices/bloc/two_touch_bloc/two_touch_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/devices/bloc/two_touch_bloc/two_touch_event.dart'; @@ -106,32 +105,43 @@ class TwoTouchBloc extends Bloc { } } - _listenToChanges() { - try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$twoTouchId'); - Stream stream = ref.onValue; + // StreamSubscription? _streamSubscription; - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = - event.snapshot.value as Map; - List statusList = []; + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$twoTouchId'); + // Stream stream = ref.onValue; + + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // print('=========${usersMap['status']}'); + // deviceStatus = TwoTouchModel.fromJson(statusList); + // if (!isClosed) { + // add(TwoTouchUpdated()); + // } + // }); + // } catch (_) {} + // } + + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } - usersMap['status'].forEach((element) { - statusList - .add(StatusModel(code: element['code'], value: element['value'])); - }); - deviceStatus = TwoTouchModel.fromJson(statusList); - if (!isClosed) { - add(TwoTouchUpdated()); - } - }); - } catch (_) {} - } _twoTouchUpdated(TwoTouchUpdated event, Emitter emit) { emit(UpdateState(twoTouchModel: deviceStatus)); diff --git a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart index 6994bcc..96a5f03 100644 --- a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart +++ b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart'; @@ -21,7 +23,8 @@ class WallSensorBloc extends Bloc { on(_getDeviceReports); } - void _fetchCeilingSensorStatus(InitialEvent event, Emitter emit) async { + void _fetchCeilingSensorStatus( + InitialEvent event, Emitter emit) async { emit(LoadingInitialState()); try { var response = await DevicesAPI.getDeviceStatus(deviceId); @@ -31,41 +34,62 @@ class WallSensorBloc extends Bloc { } deviceStatus = WallSensorModel.fromJson(statusModelList); emit(UpdateState(wallSensorModel: deviceStatus)); - // _listenToChanges(); + _listenToChanges(); } catch (e) { emit(FailedState(error: e.toString())); return; } } - _listenToChanges() { + Timer? _timer; + StreamSubscription? _streamSubscription; + + void _listenToChanges() { try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId'); + _streamSubscription?.cancel(); + DatabaseReference ref = + FirebaseDatabase.instance.ref('device-status/$deviceId'); Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) { - Map usersMap = event.snapshot.value as Map; + _streamSubscription = stream.listen((DatabaseEvent event) async { + if (_timer != null) { + await Future.delayed(const Duration(seconds: 2)); + } + Map usersMap = + event.snapshot.value as Map; List statusList = []; - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); + statusList + .add(StatusModel(code: element['code'], value: element['value'])); }); - deviceStatus = WallSensorModel.fromJson(statusList); - add(WallSensorUpdatedEvent()); + if (!isClosed) { + add(WallSensorUpdatedEvent()); + } }); } catch (_) {} } - _wallSensorUpdated(WallSensorUpdatedEvent event, Emitter emit) { + @override + Future close() async { + _streamSubscription?.cancel(); + _streamSubscription = null; + return super.close(); + } + + _wallSensorUpdated( + WallSensorUpdatedEvent event, Emitter emit) { emit(UpdateState(wallSensorModel: deviceStatus)); } - void _changeIndicator(ChangeIndicatorEvent event, Emitter emit) async { + void _changeIndicator( + ChangeIndicatorEvent event, Emitter emit) async { emit(LoadingNewSate(wallSensorModel: deviceStatus)); try { final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: deviceId, code: 'indicator', value: !event.value), deviceId); + DeviceControlModel( + deviceId: deviceId, code: 'indicator', value: !event.value), + deviceId); if (response['success'] ?? false) { deviceStatus.indicator = !event.value; @@ -74,11 +98,14 @@ class WallSensorBloc extends Bloc { emit(UpdateState(wallSensorModel: deviceStatus)); } - void _changeValue(ChangeValueEvent event, Emitter emit) async { + void _changeValue( + ChangeValueEvent event, Emitter emit) async { emit(LoadingNewSate(wallSensorModel: deviceStatus)); try { final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: deviceId, code: event.code, value: event.value), deviceId); + DeviceControlModel( + deviceId: deviceId, code: event.code, value: event.value), + deviceId); if (response['success'] ?? false) { if (event.code == 'far_detection') { @@ -93,7 +120,8 @@ class WallSensorBloc extends Bloc { emit(UpdateState(wallSensorModel: deviceStatus)); } - void _getDeviceReports(GetDeviceReportsEvent event, Emitter emit) async { + void _getDeviceReports( + GetDeviceReportsEvent event, Emitter emit) async { emit(LoadingInitialState()); try { diff --git a/lib/features/devices/bloc/water_heater_bloc/water_heater_bloc.dart b/lib/features/devices/bloc/water_heater_bloc/water_heater_bloc.dart index 40f2bc7..2316b61 100644 --- a/lib/features/devices/bloc/water_heater_bloc/water_heater_bloc.dart +++ b/lib/features/devices/bloc/water_heater_bloc/water_heater_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; @@ -35,7 +34,8 @@ class WaterHeaterBloc extends Bloc { List listSchedule = []; DateTime? selectedTime = DateTime.now(); - WaterHeaterBloc({required this.whId, required this.switchCode}) : super(WHInitialState()) { + WaterHeaterBloc({required this.whId, required this.switchCode}) + : super(WHInitialState()) { on(_fetchWaterHeaterStatus); on(_changeFirstSwitch); on(_setCounterValue); @@ -60,7 +60,8 @@ class WaterHeaterBloc extends Bloc { on(_waterHeaterUpdated); } - void _fetchWaterHeaterStatus(WaterHeaterInitial event, Emitter emit) async { + void _fetchWaterHeaterStatus( + WaterHeaterInitial event, Emitter emit) async { emit(WHLoadingState()); try { var response = await DevicesAPI.getDeviceStatus(whId); @@ -79,36 +80,51 @@ class WaterHeaterBloc extends Bloc { } } - _listenToChanges() { - try { - DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$whId'); - Stream stream = ref.onValue; + //real-time db + // StreamSubscription? _streamSubscription; + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$whId'); + // Stream stream = ref.onValue; - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = event.snapshot.value as Map; - List statusList = []; + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // deviceStatus = WHModel.fromJson(statusList); + // if (!isClosed) { + // add(WaterHeaterUpdated()); + // } + // }); + // } catch (_) {} + // } - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: element['value'])); - }); + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } - deviceStatus = WHModel.fromJson(statusList); - if (!isClosed) { - add(WaterHeaterUpdated()); - } - }); - } catch (_) {} - } - _waterHeaterUpdated(WaterHeaterUpdated event, Emitter emit) async { + + _waterHeaterUpdated( + WaterHeaterUpdated event, Emitter emit) async { emit(WHLoadingState()); emit(UpdateState(whModel: deviceStatus)); } - void _changeFirstSwitch(WaterHeaterSwitch event, Emitter emit) async { + void _changeFirstSwitch( + WaterHeaterSwitch event, Emitter emit) async { emit(LoadingNewSate(whModel: deviceStatus)); try { deviceStatus.firstSwitch = !event.whSwitch; @@ -118,7 +134,10 @@ class WaterHeaterBloc extends Bloc { } _timer = Timer(const Duration(milliseconds: 500), () async { final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: whId, code: 'switch_1', value: deviceStatus.firstSwitch), + DeviceControlModel( + deviceId: whId, + code: 'switch_1', + value: deviceStatus.firstSwitch), whId); if (!response['success']) { @@ -132,13 +151,16 @@ class WaterHeaterBloc extends Bloc { //=====================---------- timer ---------------------------------------- - void _setCounterValue(SetCounterValue event, Emitter emit) async { + void _setCounterValue( + SetCounterValue event, Emitter emit) async { emit(LoadingNewSate(whModel: deviceStatus)); int seconds = 0; try { seconds = event.duration.inSeconds; final response = await DevicesAPI.controlDevice( - DeviceControlModel(deviceId: whId, code: event.deviceCode, value: seconds), whId); + DeviceControlModel( + deviceId: whId, code: event.deviceCode, value: seconds), + whId); if (response['success'] ?? false) { if (event.deviceCode == 'countdown_1') { @@ -160,7 +182,8 @@ class WaterHeaterBloc extends Bloc { } } - void _getCounterValue(GetCounterEvent event, Emitter emit) async { + void _getCounterValue( + GetCounterEvent event, Emitter emit) async { emit(WHLoadingState()); try { var response = await DevicesAPI.getDeviceStatus(whId); @@ -250,7 +273,8 @@ class WaterHeaterBloc extends Bloc { deviceId: whId, ); List jsonData = response; - listSchedule = jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); + listSchedule = + jsonData.map((item) => ScheduleModel.fromJson(item)).toList(); emit(WHInitialState()); } on DioException catch (e) { final errorData = e.response!.data; @@ -261,12 +285,13 @@ class WaterHeaterBloc extends Bloc { int? getTimeStampWithoutSeconds(DateTime? dateTime) { if (dateTime == null) return null; - DateTime dateTimeWithoutSeconds = - DateTime(dateTime.year, dateTime.month, dateTime.day, dateTime.hour, dateTime.minute); + DateTime dateTimeWithoutSeconds = DateTime(dateTime.year, dateTime.month, + dateTime.day, dateTime.hour, dateTime.minute); return dateTimeWithoutSeconds.millisecondsSinceEpoch ~/ 1000; } - Future toggleChange(ToggleScheduleEvent event, Emitter emit) async { + Future toggleChange( + ToggleScheduleEvent event, Emitter emit) async { try { emit(WHLoadingState()); final response = await DevicesAPI.changeSchedule( @@ -284,7 +309,8 @@ class WaterHeaterBloc extends Bloc { } } - Future deleteSchedule(DeleteScheduleEvent event, Emitter emit) async { + Future deleteSchedule( + DeleteScheduleEvent event, Emitter emit) async { try { emit(WHLoadingState()); final response = await DevicesAPI.deleteSchedule( @@ -303,7 +329,8 @@ class WaterHeaterBloc extends Bloc { } } - void _toggleCreateCirculate(ToggleCreateCirculate event, Emitter emit) { + void _toggleCreateCirculate( + ToggleCreateCirculate event, Emitter emit) { emit(WHLoadingState()); createCirculate = !createCirculate; selectedDays.clear(); @@ -311,13 +338,15 @@ class WaterHeaterBloc extends Bloc { emit(UpdateCreateScheduleState(createCirculate)); } - void toggleSelectedIndex(ToggleSelectedEvent event, Emitter emit) { + void toggleSelectedIndex( + ToggleSelectedEvent event, Emitter emit) { emit(WHLoadingState()); selectedTabIndex = event.index; emit(ChangeSlidingSegmentState(value: selectedTabIndex)); } - void toggleCreateSchedule(ToggleCreateScheduleEvent event, Emitter emit) { + void toggleCreateSchedule( + ToggleCreateScheduleEvent event, Emitter emit) { emit(WHLoadingState()); createSchedule = !createSchedule; selectedDays.clear(); @@ -366,8 +395,8 @@ class WaterHeaterBloc extends Bloc { List groupWaterHeaterList = []; bool allSwitchesOn = true; - void _changeFirstWizardSwitch( - ChangeFirstWizardSwitchStatusEvent event, Emitter emit) async { + void _changeFirstWizardSwitch(ChangeFirstWizardSwitchStatusEvent event, + Emitter emit) async { emit(LoadingNewSate(whModel: deviceStatus)); try { bool allSwitchesValue = true; @@ -379,7 +408,8 @@ class WaterHeaterBloc extends Bloc { allSwitchesValue = false; } }); - emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue)); + emit(UpdateGroupState( + twoGangList: groupWaterHeaterList, allSwitches: allSwitchesValue)); final response = await DevicesAPI.deviceBatchController( code: 'switch_1', @@ -394,7 +424,8 @@ class WaterHeaterBloc extends Bloc { } } - void _fetchWHWizardStatus(InitialWizardEvent event, Emitter emit) async { + void _fetchWHWizardStatus( + InitialWizardEvent event, Emitter emit) async { emit(WHLoadingState()); try { devicesList = []; @@ -404,7 +435,8 @@ class WaterHeaterBloc extends Bloc { HomeCubit.getInstance().selectedSpace?.id ?? '', 'WH'); for (int i = 0; i < devicesList.length; i++) { - var response = await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); + var response = + await DevicesAPI.getDeviceStatus(devicesList[i].uuid ?? ''); List statusModelList = []; for (var status in response['status']) { statusModelList.add(StatusModel.fromJson(status)); @@ -426,23 +458,27 @@ class WaterHeaterBloc extends Bloc { return true; }); } - emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn)); + emit(UpdateGroupState( + twoGangList: groupWaterHeaterList, allSwitches: allSwitchesOn)); } catch (e) { // emit(FailedState(error: e.toString())); return; } } - void _groupAllOn(GroupAllOnEvent event, Emitter emit) async { + void _groupAllOn( + GroupAllOnEvent event, Emitter emit) async { emit(LoadingNewSate(whModel: deviceStatus)); try { for (int i = 0; i < groupWaterHeaterList.length; i++) { groupWaterHeaterList[i].firstSwitch = true; } - emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: true)); + emit(UpdateGroupState( + twoGangList: groupWaterHeaterList, allSwitches: true)); - List allDeviceIds = groupWaterHeaterList.map((device) => device.deviceId).toList(); + List allDeviceIds = + groupWaterHeaterList.map((device) => device.deviceId).toList(); final response = await DevicesAPI.deviceBatchController( code: 'switch_1', @@ -460,15 +496,18 @@ class WaterHeaterBloc extends Bloc { } } - void _groupAllOff(GroupAllOffEvent event, Emitter emit) async { + void _groupAllOff( + GroupAllOffEvent event, Emitter emit) async { emit(LoadingNewSate(whModel: deviceStatus)); try { for (int i = 0; i < groupWaterHeaterList.length; i++) { groupWaterHeaterList[i].firstSwitch = false; } - emit(UpdateGroupState(twoGangList: groupWaterHeaterList, allSwitches: false)); + emit(UpdateGroupState( + twoGangList: groupWaterHeaterList, allSwitches: false)); - List allDeviceIds = groupWaterHeaterList.map((device) => device.deviceId).toList(); + List allDeviceIds = + groupWaterHeaterList.map((device) => device.deviceId).toList(); final response = await DevicesAPI.deviceBatchController( code: 'switch_1', diff --git a/lib/features/devices/bloc/water_leak_bloc/water_leak_bloc.dart b/lib/features/devices/bloc/water_leak_bloc/water_leak_bloc.dart index 300c4f4..c4f70a1 100644 --- a/lib/features/devices/bloc/water_leak_bloc/water_leak_bloc.dart +++ b/lib/features/devices/bloc/water_leak_bloc/water_leak_bloc.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'package:dio/dio.dart'; -import 'package:firebase_database/firebase_database.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/devices/bloc/water_leak_bloc/water_leak_event.dart'; import 'package:syncrow_app/features/devices/bloc/water_leak_bloc/water_leak_state.dart'; @@ -21,7 +20,6 @@ class WaterLeakBloc extends Bloc { on(_toggleClosingReminder); on(_toggleWaterLeakAlarm); } - Timer? _timer; bool lowBattery = false; bool closingReminder = false; bool waterAlarm = false; @@ -134,32 +132,42 @@ class WaterLeakBloc extends Bloc { emit(WaterLeakFailedState(errorMessage: errorMessage)); } } + // Timer? _timer; + // StreamSubscription? _streamSubscription; + // void _listenToChanges() { + // try { + // _streamSubscription?.cancel(); + // DatabaseReference ref = + // FirebaseDatabase.instance.ref('device-status/$WLId'); + // Stream stream = ref.onValue; - _listenToChanges() { - try { - DatabaseReference ref = - FirebaseDatabase.instance.ref('device-status/$WLId'); - Stream stream = ref.onValue; + // _streamSubscription = stream.listen((DatabaseEvent event) async { + // if (_timer != null) { + // await Future.delayed(const Duration(seconds: 2)); + // } + // Map usersMap = + // event.snapshot.value as Map; + // List statusList = []; + // usersMap['status'].forEach((element) { + // statusList + // .add(StatusModel(code: element['code'], value: element['value'])); + // }); + // deviceStatus = WaterLeakModel.fromJson(statusList); + // if (!isClosed) { + // add( + // WaterLeakSwitch(switchD: deviceStatus.waterContactState), + // ); + // } + // }); + // } catch (_) {} + // } - stream.listen((DatabaseEvent event) async { - if (_timer != null) { - await Future.delayed(const Duration(seconds: 2)); - } - Map usersMap = - event.snapshot.value as Map; - List statusList = []; + // @override + // Future close() async { + // _streamSubscription?.cancel(); + // _streamSubscription = null; + // return super.close(); + // } - usersMap['status'].forEach((element) { - statusList.add(StatusModel(code: element['code'], value: true)); - }); - deviceStatus = WaterLeakModel.fromJson(statusList); - if (!isClosed) { - add( - WaterLeakSwitch(switchD: deviceStatus.waterContactState), - ); - } - }); - } catch (_) {} - } } diff --git a/lib/features/devices/view/widgets/ACs/acs_view.dart b/lib/features/devices/view/widgets/ACs/acs_view.dart index 7ced282..f57786d 100644 --- a/lib/features/devices/view/widgets/ACs/acs_view.dart +++ b/lib/features/devices/view/widgets/ACs/acs_view.dart @@ -23,6 +23,7 @@ class ACsView extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( + create: (context) => ACsBloc(acId: deviceModel?.uuid ?? '') ..add(AcsInitial(allAcs: deviceModel != null ? false : true)), child: BlocBuilder( diff --git a/lib/features/devices/view/widgets/room_page_switch.dart b/lib/features/devices/view/widgets/room_page_switch.dart index 2893b63..5d9488c 100644 --- a/lib/features/devices/view/widgets/room_page_switch.dart +++ b/lib/features/devices/view/widgets/room_page_switch.dart @@ -119,6 +119,8 @@ Future showDeviceInterface( required BuildContext context, required isAllDevices, List? allDevices}) async { + print('object-----${device.uuid} ${device.name}'); + final devicesCubit = context.read(); switch (device.productType) {