// ignore_for_file: constant_identifier_names, unused_import import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_app/features/app_layout/bloc/home_cubit.dart'; import 'package:syncrow_app/features/app_layout/model/space_model.dart'; import 'package:syncrow_app/features/devices/model/device_category_model.dart'; import 'package:syncrow_app/features/devices/model/device_control_model.dart'; import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/curtains/curtain_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/lights/lights_view.dart'; import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart'; import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_view.dart'; import 'package:syncrow_app/services/api/devices_api.dart'; import 'package:syncrow_app/services/api/network_exception.dart'; import 'package:syncrow_app/services/api/spaces_api.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; part 'devices_state.dart'; class DevicesCubit extends Cubit { DevicesCubit._() : super(DevicesInitial()) { if (HomeCubit.getInstance().selectedSpace != null) { fetchGroups(HomeCubit.getInstance().selectedSpace!.id!); for (var room in HomeCubit.getInstance().selectedSpace!.rooms!) { fetchDevicesByRoomId(room.id!); } } } static DevicesCubit? _instance; static DevicesCubit getInstance() { return _instance ??= DevicesCubit._(); } DeviceModel? selectedDevice; @override Future close() { _instance = null; return super.close(); } void emitSafe(DevicesState newState) { final cubit = this; if (!cubit.isClosed) { cubit.emit(newState); } } static DevicesCubit get(context) => BlocProvider.of(context); static List? allCategories; selectCategory(int index) { for (var i = 0; i < allCategories!.length; i++) { if (i == index) { allCategories![i].isSelected = true; } else { allCategories![i].isSelected = false; } } emitSafe(DevicesCategoryChanged()); } unselectAllCategories() { for (var category in allCategories!) { category.isSelected = false; } emitSafe(DevicesCategoryChanged()); } Widget? get chosenCategoryView { if (allCategories != null) { for (var category in allCategories!) { if (category.isSelected) { switch (category.type) { case DeviceType.AC: return const ACsView(); case DeviceType.LightBulb: return const LightsView(); case DeviceType.DoorLock: return const DoorView(); case DeviceType.Curtain: return const CurtainView(); // case DeviceType.ThreeGang: // return const ThreeGangSwitchesView(); case DeviceType.Gateway: return const GateWayView(); default: return null; } } } } return null; } DevicesCategoryModel? get chosenCategory { for (var category in allCategories!) { if (category.isSelected) { return category; } } return null; } selectDevice(DeviceModel device) { for (var category in allCategories!) { if (category.devices != null) { for (var device in category.devices!) { if (device.isSelected) { category.isSelected = false; emitSafe(DeviceSelected()); return; } } } } device.isSelected = !device.isSelected; emitSafe(DeviceSelected()); } DeviceModel? getSelectedDevice() { for (var category in allCategories!) { if (category.devices != null) { for (var device in category.devices!) { if (device.isSelected) { return device; } } } } return null; } changeCategorySwitchValue(DevicesCategoryModel category) { if (category.devicesStatus != null) { category.devicesStatus = !category.devicesStatus!; if (category.devices != null) { for (var device in category.devices!) { device.isOnline = category.devicesStatus; } } } else { category.devicesStatus = true; if (category.devices != null) { for (var device in category.devices!) { device.isOnline = true; } } } updateDevicesStatus(category); emitSafe(CategorySwitchChanged()); } turnOnOffDevice(DeviceModel device) { device.isOnline = !device.isOnline!; DevicesCategoryModel category = allCategories!.firstWhere((category) { if (category.devices != null) { return category.devices!.contains(device); } else { return false; } }); updateDevicesStatus(category); emitSafe(DeviceSwitchChanged()); } updateDevicesStatus(DevicesCategoryModel category) { if (category.devices != null) { if (category.devices!.isNotEmpty) { bool? tempStatus = category.devices![0].isOnline; for (var ac in category.devices!) { //check if there any ac have a different status than the initial ==> turn off the universal switch if (ac.isOnline != tempStatus) { category.devicesStatus = null; emitSafe(DeviceSwitchChanged()); return; } category.devicesStatus = tempStatus; emitSafe(DeviceSwitchChanged()); } } else { category.devicesStatus = null; emitSafe(DeviceSwitchChanged()); } } } turnAllDevicesOff(DevicesCategoryModel category) { if (category.devices != null) { if (category.devices!.isNotEmpty) { for (var device in category.devices!) { device.isOnline = false; } changeCategorySwitchValue(category); updateDevicesStatus(category); emitSafe(CategorySwitchChanged()); } } } turnAllDevicesOn(DevicesCategoryModel category) { if (category.devices != null) { if (category.devices!.isNotEmpty) { for (var device in category.devices!) { device.isOnline = true; } changeCategorySwitchValue(category); updateDevicesStatus(category); emitSafe(CategorySwitchChanged()); } } } areAllDevicesOff(DevicesCategoryModel category) { if (category.devices != null) { for (var device in category.devices!) { if (device.isOnline ?? false) { category.devicesStatus = false; emitSafe(CategorySwitchChanged()); return; } } } } clearCategoriesSelection(BuildContext context) { for (var category in allCategories!) { category.isSelected = false; if (category.devices != null) { for (var device in category.devices!) { device.isSelected = false; } } } Navigator.popUntil(context, (route) => route.isFirst); emitSafe(DevicesCategoryChanged()); } ///////////////////////// API CALLS ////////////////////////// deviceControl(DeviceControlModel control, String deviceId) async { emitSafe(DeviceControlLoading( code: control.code, )); try { var response = await DevicesAPI.controlDevice(control); if (response['success'] ?? false) { emitSafe(DeviceControlSuccess(code: control.code)); //this delay is to give tuya server time to update the status Future.delayed(const Duration(milliseconds: 400), () { getDevicesStatues( deviceId, HomeCubit.getInstance() .selectedSpace! .rooms! .indexOf(HomeCubit.getInstance().selectedRoom!), code: control.code); }); } else { emitSafe(DeviceControlError('Failed to control the device')); } } catch (failure) { emitSafe(DeviceControlError(failure.toString())); return; } } fetchGroups(int spaceId) async { emitSafe(DevicesCategoriesLoading()); try { allCategories = await DevicesAPI.fetchGroups(spaceId); } catch (e) { emitSafe(DevicesCategoriesError(e.toString())); return; } if (allCategories!.isNotEmpty && allCategories != null) { emitSafe(DevicesCategoriesSuccess()); } else { emitSafe(DevicesCategoriesError('No Groups found')); } } fetchDevicesByRoomId(int? roomId) async { if (roomId == null) return; emitSafe(GetDevicesLoading()); int roomIndex = HomeCubit.getInstance() .selectedSpace! .rooms! .indexWhere((element) => element.id == roomId); try { HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices = await DevicesAPI.getDevicesByRoomId(roomId); } catch (e) { emitSafe(GetDevicesError(e.toString())); return; } emitSafe(GetDevicesSuccess()); //get status for each device //TODO get devices status per page via page controller instead of getting all devices status at once for (var device in HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices!) { getDevicesStatues(device.id!, roomIndex); } } getDevicesStatues(String deviceId, int roomIndex, {String? code}) async { emitSafe(GetDeviceStatusLoading(code: code)); int deviceIndex = HomeCubit.getInstance() .selectedSpace! .rooms![roomIndex] .devices! .indexWhere((element) => element.id == deviceId); List statuses = []; try { var response = await DevicesAPI.getDeviceStatus(deviceId); for (var status in response['result']['status']) { statuses.add(StatusModel.fromJson(status)); } } catch (e) { emitSafe(GetDeviceStatusError(e.toString())); return; } HomeCubit.getInstance() .selectedSpace! .rooms![roomIndex] .devices![deviceIndex] .status = statuses; emitSafe(GetDeviceStatusSuccess(code: code)); } ///Lights onHorizontalDragUpdate(DeviceModel light, double dx, double screenWidth) { double newBrightness = (dx / (screenWidth - 15) * 100); if (newBrightness > 100) { newBrightness = 100; } else if (newBrightness < 0) { newBrightness = 0; } // setBrightness(light, newBrightness); } Map lightModes = { 0: LightMode.Doze, 1: LightMode.Relax, 2: LightMode.Reading, 3: LightMode.Energizing, }; // setLightingMode(DeviceModel light, LightMode mode) { // light.lightingMode = // lightModes.entries.firstWhere((element) => element.value == mode).key; // emitSafe(LightModeChanged(mode)); // } // // toggleLight(DeviceModel light) { // light.isOnline != null ? light.isOnline = !light.isOnline! : light.isOnline = true; // emitSafe(LightToggled(light)); // } // // setColor(DeviceModel light, int color) { // light.color = color; // emitSafe(LightColorChanged(color)); // } // // int getBrightness(DeviceModel light) { // return light.brightness.toInt(); // } // setBrightness(DeviceModel light, double value) { // value = (value / 5).ceil() * 5; // if (value != light.brightness) { // light.brightness = value; // emitSafe(LightBrightnessChanged(value)); // } // } } enum LightMode { Doze, Relax, Reading, Energizing, }