mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 01:35:23 +00:00
561 lines
15 KiB
Dart
561 lines
15 KiB
Dart
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/spaces_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/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/lights_switches/light_switches.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/utils/resource_manager/constants.dart';
|
|
|
|
part 'devices_state.dart';
|
|
|
|
class DevicesCubit extends Cubit<DevicesState> {
|
|
DevicesCubit() : super(DevicesInitial()) {
|
|
fetchGroups(SpacesCubit.selectedSpace!);
|
|
}
|
|
|
|
static DevicesCubit get(context) => BlocProvider.of(context);
|
|
|
|
static List<DevicesCategoryModel> allCategories = [
|
|
// DevicesCategoryModel(
|
|
// devices: [
|
|
// DeviceModel(
|
|
// name: "Living Room AC",
|
|
// id: 0,
|
|
// functions: [],
|
|
// status: false,
|
|
// temperature: 20,
|
|
// fanSpeed: 0,
|
|
// tempMode: 0,
|
|
// coolTo: 20,
|
|
// type: DeviceType.AC,
|
|
// image: '',
|
|
// timer: null,
|
|
// bounds: Bounds(
|
|
// min: 20,
|
|
// max: 30,
|
|
// ),
|
|
// ),
|
|
// DeviceModel(
|
|
// name: "Master Bedroom AC",
|
|
// id: 1,
|
|
// functions: [],
|
|
// status: false,
|
|
// temperature: 20,
|
|
// fanSpeed: 0,
|
|
// tempMode: 0,
|
|
// coolTo: 20,
|
|
// type: DeviceType.AC,
|
|
// image: '',
|
|
// timer: null,
|
|
// bounds: Bounds(
|
|
// min: 20,
|
|
// max: 30,
|
|
// ),
|
|
// ),
|
|
// DeviceModel(
|
|
// name: "Kitchen AC",
|
|
// id: 2,
|
|
// functions: [],
|
|
// status: false,
|
|
// temperature: 20,
|
|
// fanSpeed: 0,
|
|
// tempMode: 0,
|
|
// coolTo: 20,
|
|
// type: DeviceType.AC,
|
|
// image: '',
|
|
// timer: null,
|
|
// bounds: Bounds(
|
|
// min: 20,
|
|
// max: 30,
|
|
// ),
|
|
// ),
|
|
// DeviceModel(
|
|
// name: "Bathroom AC",
|
|
// id: 3,
|
|
// functions: [],
|
|
// status: false,
|
|
// temperature: 20,
|
|
// fanSpeed: 0,
|
|
// tempMode: 0,
|
|
// coolTo: 20,
|
|
// type: DeviceType.AC,
|
|
// image: '',
|
|
// timer: null,
|
|
// bounds: Bounds(
|
|
// min: 20,
|
|
// max: 30,
|
|
// ),
|
|
// ),
|
|
// ],
|
|
// icon: Assets.iconsAC,
|
|
// name: 'ACs',
|
|
// type: DeviceType.AC,
|
|
// page: const ACsView(),
|
|
// ),
|
|
// DevicesCategoryModel(
|
|
// devices: [
|
|
// DeviceModel(
|
|
// name: "Living Room Light",
|
|
// id: 0,
|
|
// functions: [],
|
|
// status: false,
|
|
// color: 0,
|
|
// brightness: 20,
|
|
// lightingMode: 1,
|
|
// timer: null,
|
|
// type: DeviceType.Lights,
|
|
// image: '',
|
|
// recentColors: [
|
|
// 0xFF83D9FF,
|
|
// 0xFFFC3E81,
|
|
// 0xFFC0FF66,
|
|
// 0xFFFDC242,
|
|
// ],
|
|
// ),
|
|
// DeviceModel(
|
|
// name: "Master Bedroom Light",
|
|
// id: 1,
|
|
// functions: [],
|
|
// status: false,
|
|
// color: 2,
|
|
// brightness: 40,
|
|
// lightingMode: 1,
|
|
// timer: null,
|
|
// type: DeviceType.Lights,
|
|
// image: '',
|
|
// recentColors: [
|
|
// 0xFF83D9FF,
|
|
// 0xFFFC3E81,
|
|
// 0xFFC0FF66,
|
|
// 0xFFFDC242,
|
|
// ],
|
|
// ),
|
|
// DeviceModel(
|
|
// name: "Kitchen Light",
|
|
// id: 2,
|
|
// functions: [],
|
|
// status: false,
|
|
// color: 1,
|
|
// brightness: 60,
|
|
// lightingMode: 1,
|
|
// timer: null,
|
|
// type: DeviceType.Lights,
|
|
// image: '',
|
|
// recentColors: [
|
|
// 0xFF83D9FF,
|
|
// 0xFFFC3E81,
|
|
// 0xFFC0FF66,
|
|
// 0xFFFDC242,
|
|
// ],
|
|
// ),
|
|
// DeviceModel(
|
|
// name: "Bathroom Light",
|
|
// id: 3,
|
|
// functions: [],
|
|
// status: false,
|
|
// color: 3,
|
|
// brightness: 80,
|
|
// lightingMode: 1,
|
|
// timer: null,
|
|
// type: DeviceType.Lights,
|
|
// image: '',
|
|
// recentColors: [
|
|
// 0xFF83D9FF,
|
|
// 0xFFFC3E81,
|
|
// 0xFFC0FF66,
|
|
// 0xFFFDC242,
|
|
// ],
|
|
// ),
|
|
// DeviceModel(
|
|
// name: "Balcony Light",
|
|
// id: 4,
|
|
// functions: [],
|
|
// status: false,
|
|
// color: 4,
|
|
// brightness: 100,
|
|
// lightingMode: 1,
|
|
// timer: null,
|
|
// type: DeviceType.Lights,
|
|
// image: '',
|
|
// recentColors: [
|
|
// 0xFF83D9FF,
|
|
// 0xFFFC3E81,
|
|
// 0xFFC0FF66,
|
|
// 0xFFFDC242,
|
|
// ],
|
|
// ),
|
|
// ],
|
|
// icon: Assets.iconsLight,
|
|
// name: 'Lights',
|
|
// type: DeviceType.Lights,
|
|
// page: const LightsView(),
|
|
// ),
|
|
// DevicesCategoryModel(
|
|
// devices: [],
|
|
// icon: Assets.iconsDoorLock,
|
|
// name: 'Doors',
|
|
// type: DeviceType.DoorLock,
|
|
// page: const DoorView(),
|
|
// ),
|
|
// DevicesCategoryModel(
|
|
// devices: [
|
|
// DeviceModel(
|
|
// openPercentage: 10,
|
|
// id: 1,
|
|
// functions: [],
|
|
// name: "Living Room Curtain",
|
|
// status: false,
|
|
// type: DeviceType.Curtain,
|
|
// image: '',
|
|
// timer: null,
|
|
// ),
|
|
// DeviceModel(
|
|
// openPercentage: 20,
|
|
// id: 2,
|
|
// functions: [],
|
|
// name: "Master Bedroom Curtain",
|
|
// status: false,
|
|
// type: DeviceType.Curtain,
|
|
// image: '',
|
|
// timer: null,
|
|
// ),
|
|
// ],
|
|
// icon: Assets.iconsCurtain,
|
|
// name: 'Curtains',
|
|
// type: DeviceType.Curtain,
|
|
// page: const CurtainView(),
|
|
// ),
|
|
// DevicesCategoryModel(
|
|
// devices: [],
|
|
// icon: Assets.icons3GangSwitch,
|
|
// name: 'Bedroom Lights',
|
|
// type: DeviceType.ThreeGang,
|
|
// page: const LightSwitchesView(),
|
|
// ),
|
|
// DevicesCategoryModel(
|
|
// devices: [],
|
|
// icon: Assets.iconsGateway,
|
|
// name: 'Gateway',
|
|
// type: DeviceType.Gateway,
|
|
// page: const GateWayView(),
|
|
// ),
|
|
];
|
|
|
|
selectCategory(int index) {
|
|
for (var i = 0; i < allCategories.length; i++) {
|
|
if (i == index) {
|
|
allCategories[i].isSelected = true;
|
|
} else {
|
|
allCategories[i].isSelected = false;
|
|
}
|
|
}
|
|
emit(DevicesCategoryChanged());
|
|
}
|
|
|
|
unselectAllCategories() {
|
|
for (var category in allCategories) {
|
|
category.isSelected = false;
|
|
}
|
|
emit(DevicesCategoryChanged());
|
|
}
|
|
|
|
Widget? get chosenCategoryView {
|
|
for (var category in allCategories) {
|
|
if (category.isSelected) {
|
|
switch (category.type) {
|
|
case DeviceType.AC:
|
|
return const ACsView();
|
|
case DeviceType.Lights:
|
|
return const LightsView();
|
|
case DeviceType.DoorLock:
|
|
return const DoorView();
|
|
case DeviceType.Curtain:
|
|
return const CurtainView();
|
|
case DeviceType.ThreeGang:
|
|
return const LightSwitchesView();
|
|
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;
|
|
emit(DeviceSelected());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
device.isSelected = !device.isSelected;
|
|
emit(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.status = category.devicesStatus;
|
|
}
|
|
}
|
|
} else {
|
|
category.devicesStatus = true;
|
|
if (category.devices != null) {
|
|
for (var device in category.devices!) {
|
|
device.status = true;
|
|
}
|
|
}
|
|
}
|
|
updateDevicesStatus(category);
|
|
|
|
emit(CategorySwitchChanged());
|
|
}
|
|
|
|
turnOnOffDevice(DeviceModel device) {
|
|
device.status = !device.status!;
|
|
DevicesCategoryModel category = allCategories.firstWhere((category) {
|
|
if (category.devices != null) {
|
|
return category.devices!.contains(device);
|
|
} else {
|
|
return false;
|
|
}
|
|
});
|
|
updateDevicesStatus(category);
|
|
emit(DeviceSwitchChanged());
|
|
}
|
|
|
|
updateDevicesStatus(DevicesCategoryModel category) {
|
|
if (category.devices != null) {
|
|
if (category.devices!.isNotEmpty) {
|
|
bool? tempStatus = category.devices![0].status;
|
|
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.status != tempStatus) {
|
|
category.devicesStatus = null;
|
|
emit(DeviceSwitchChanged());
|
|
return;
|
|
}
|
|
category.devicesStatus = tempStatus;
|
|
emit(DeviceSwitchChanged());
|
|
}
|
|
} else {
|
|
category.devicesStatus = null;
|
|
emit(DeviceSwitchChanged());
|
|
}
|
|
}
|
|
}
|
|
|
|
turnAllDevicesOff(DevicesCategoryModel category) {
|
|
if (category.devices != null) {
|
|
if (category.devices!.isNotEmpty) {
|
|
for (var device in category.devices!) {
|
|
device.status = false;
|
|
}
|
|
changeCategorySwitchValue(category);
|
|
updateDevicesStatus(category);
|
|
emit(CategorySwitchChanged());
|
|
}
|
|
}
|
|
}
|
|
|
|
turnAllDevicesOn(DevicesCategoryModel category) {
|
|
if (category.devices != null) {
|
|
if (category.devices!.isNotEmpty) {
|
|
for (var device in category.devices!) {
|
|
device.status = true;
|
|
}
|
|
changeCategorySwitchValue(category);
|
|
updateDevicesStatus(category);
|
|
emit(CategorySwitchChanged());
|
|
}
|
|
}
|
|
}
|
|
|
|
areAllDevicesOff(DevicesCategoryModel category) {
|
|
if (category.devices != null) {
|
|
for (var device in category.devices!) {
|
|
if (device.status ?? false) {
|
|
category.devicesStatus = false;
|
|
emit(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);
|
|
|
|
emit(DevicesCategoryChanged());
|
|
}
|
|
|
|
deviceControl(DeviceControlModel control) async {
|
|
emit(DeviceControlLoading());
|
|
try {
|
|
await DevicesAPI.controlDevice(control);
|
|
emit(DeviceControlSuccess());
|
|
} on DioException catch (e) {
|
|
emit(DeviceControlError(ServerFailure.fromDioError(e).errMessage));
|
|
}
|
|
}
|
|
|
|
fetchGroups(
|
|
SpaceModel space,
|
|
) async {
|
|
try {
|
|
if (state is! DevicesCategoriesLoading) {
|
|
emit(DevicesCategoriesLoading());
|
|
allCategories = await DevicesAPI.fetchGroups(space.id!);
|
|
} else {
|
|
return;
|
|
}
|
|
emit(DevicesCategoriesSuccess());
|
|
} on DioException catch (error) {
|
|
emit(
|
|
DevicesCategoriesError(ServerFailure.fromDioError(error).errMessage),
|
|
);
|
|
}
|
|
}
|
|
|
|
///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<int, LightMode> 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;
|
|
// emit(LightModeChanged(mode));
|
|
// }
|
|
//
|
|
// toggleLight(DeviceModel light) {
|
|
// light.status != null ? light.status = !light.status! : light.status = true;
|
|
// emit(LightToggled(light));
|
|
// }
|
|
//
|
|
// setColor(DeviceModel light, int color) {
|
|
// light.color = color;
|
|
// emit(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;
|
|
// emit(LightBrightnessChanged(value));
|
|
// }
|
|
// }
|
|
|
|
///ACs
|
|
// DeviceModel? getSelectedAC() {
|
|
// for (var ac in category.devices) {
|
|
// if (ac is DeviceModel && ac.isSelected) {
|
|
// return ac;
|
|
// }
|
|
// }
|
|
// return null;
|
|
// }
|
|
//
|
|
// void setTempToAll(double temperature) {
|
|
// for (DeviceModel ac in category.devices) {
|
|
// if (ac is DeviceModel) {
|
|
// if (ac.temperature != temperature &&
|
|
// ac.bounds.min <= temperature &&
|
|
// temperature <= ac.bounds.max) {
|
|
// setACTemp(ac, temperature);
|
|
// }
|
|
// }
|
|
// }
|
|
// universalACTemp = temperature;
|
|
// emit(ACsTempChanged(temperature));
|
|
// }
|
|
//
|
|
// void setACTemp(DeviceModel model, double temp) {
|
|
// if (model.bounds.min <= temp && temp <= model.bounds.max) {
|
|
// model.temperature = temp;
|
|
// }
|
|
// emit(ACsTempChanged(temp));
|
|
// }
|
|
//
|
|
// double getTemp(int index) {
|
|
// var device = category.devices[index];
|
|
// if (device is DeviceModel) {
|
|
// return device.temperature;
|
|
// }
|
|
// return 0.0; // or any default value you prefer
|
|
// }
|
|
}
|
|
|
|
enum LightMode {
|
|
Doze,
|
|
Relax,
|
|
Reading,
|
|
Energizing,
|
|
}
|