mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-14 17:25:47 +00:00
748 lines
24 KiB
Dart
748 lines
24 KiB
Dart
// 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_list_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/doors_list_view.dart';
|
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
|
import 'package:syncrow_app/services/api/home_management_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<DevicesState> {
|
|
Future<void> _initializeDevices(SpaceModel selectedSpace) async {
|
|
// Fetch devices for each room in the selected space
|
|
for (var room in selectedSpace.subspaces) {
|
|
await fetchDevicesByRoomId(selectedSpace, room.id!);
|
|
}
|
|
|
|
// Fetch groups based on the selected space ID
|
|
await fetchGroups(selectedSpace.id);
|
|
await fetchAllDevices(selectedSpace);
|
|
}
|
|
|
|
DevicesCubit._() : super(DevicesInitial()) {
|
|
final selectedSpace = HomeCubit.getInstance().selectedSpace;
|
|
final spaces = HomeCubit.getInstance().spaces;
|
|
|
|
if (selectedSpace != null && spaces != null && spaces.isNotEmpty) {
|
|
_initializeDevices(selectedSpace);
|
|
}
|
|
}
|
|
|
|
static DevicesCubit? _instance;
|
|
static DevicesCubit getInstance() {
|
|
return _instance ??= DevicesCubit._();
|
|
}
|
|
|
|
@override
|
|
Future<void> 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);
|
|
|
|
List<DevicesCategoryModel>? 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 DoorsListView();
|
|
case DeviceType.Curtain:
|
|
return const CurtainListView();
|
|
// case DeviceType.ThreeGang:
|
|
// return const ThreeGangSwitchesView();
|
|
// case DeviceType.Gateway:
|
|
// return const GateWayView();
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Getter to retrieve all devices from HomeCubit
|
|
|
|
// 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, deviceId);
|
|
|
|
// 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), () {
|
|
// fetchDevicesStatues(
|
|
// deviceId,
|
|
// HomeCubit.getInstance()
|
|
// .selectedSpace!
|
|
// .subspaces
|
|
// .indexOf(HomeCubit.getInstance().selectedRoom!),
|
|
// code: control.code);
|
|
// // });
|
|
// } else {
|
|
// emitSafe(DeviceControlError('Failed to control the device'));
|
|
// }
|
|
// } catch (failure) {
|
|
// emitSafe(DeviceControlError(failure.toString()));
|
|
// return;
|
|
// }
|
|
// }
|
|
|
|
fetchGroups(String spaceId) async {
|
|
emitSafe(GetDevicesLoading());
|
|
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(SpaceModel? unit, String? roomId) async {
|
|
if (roomId == null) return;
|
|
|
|
emitSafe(GetDevicesLoading());
|
|
int roomIndex = HomeCubit.getInstance()
|
|
.selectedSpace!
|
|
.subspaces
|
|
.indexWhere((element) => element.id == roomId);
|
|
try {
|
|
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices =
|
|
await DevicesAPI.getDevicesByRoomId(
|
|
communityUuid: unit!.community.uuid,
|
|
spaceUuid: unit.id,
|
|
roomId: roomId);
|
|
} catch (e) {
|
|
emitSafe(GetDevicesError(e.toString()));
|
|
return;
|
|
}
|
|
final devices =
|
|
HomeCubit.getInstance().selectedSpace!.subspaces[roomIndex].devices;
|
|
emitSafe(GetDevicesSuccess(devices));
|
|
|
|
//get status for each device
|
|
//TODO get devices status per page via page controller instead of getting all devices status at once
|
|
// List<DeviceModel> devices = HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices!;
|
|
// if (devices.isNotEmpty) {
|
|
// for (var device in devices) {
|
|
// fetchDevicesStatues(device.uuid!, roomIndex);
|
|
// }
|
|
// }
|
|
}
|
|
|
|
fetchDevicesStatues(String deviceUuid, int roomIndex, {String? code}) async {
|
|
emitSafe(GetDeviceStatusLoading(code: code));
|
|
int deviceIndex = HomeCubit.getInstance()
|
|
.selectedSpace!
|
|
.subspaces[roomIndex]
|
|
.devices!
|
|
.indexWhere((element) => element.uuid == deviceUuid);
|
|
List<StatusModel> statuses = [];
|
|
try {
|
|
var response = await DevicesAPI.getDeviceStatus(deviceUuid);
|
|
for (var status in response['status']) {
|
|
statuses.add(StatusModel.fromJson(status));
|
|
}
|
|
} catch (e) {
|
|
emitSafe(GetDeviceStatusError(e.toString()));
|
|
return;
|
|
}
|
|
HomeCubit.getInstance()
|
|
.selectedSpace!
|
|
.subspaces[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<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;
|
|
// 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));
|
|
// }
|
|
// }
|
|
// List<DeviceModel> _fetchedDevices = [];
|
|
|
|
// List<DeviceModel> get allDevices => _fetchedDevices;
|
|
List<DeviceModel> allDevices = [];
|
|
|
|
Future<void> fetchAllDevices(SpaceModel? unit) async {
|
|
emitSafe(GetDevicesLoading());
|
|
try {
|
|
final devices = await DevicesAPI.getAllDevices(
|
|
communityUuid: unit!.community.uuid,
|
|
spaceUuid: unit.id,
|
|
);
|
|
allDevices = devices;
|
|
emitSafe(GetDevicesSuccess(allDevices));
|
|
} catch (e) {
|
|
emitSafe(GetDevicesError(e.toString()));
|
|
}
|
|
}
|
|
|
|
bool isDeviceOn(DeviceModel device) {
|
|
final switchStatuses = device.status.where(
|
|
(s) => (s.code?.startsWith('switch') ?? false),
|
|
);
|
|
final anySwitchFalse = switchStatuses.any((s) => s.value == false);
|
|
return !anySwitchFalse;
|
|
}
|
|
|
|
void updateDeviceStatus(String deviceId, bool newToggleStatus) {
|
|
emitSafe(GetDevicesLoading());
|
|
|
|
// Create a fresh copy of the device list.
|
|
final updatedDevices = List<DeviceModel>.from(allDevices);
|
|
|
|
for (int i = 0; i < updatedDevices.length; i++) {
|
|
final device = updatedDevices[i];
|
|
if (device.uuid == deviceId) {
|
|
updatedDevices[i] = DeviceModel(
|
|
activeTime: device.activeTime,
|
|
localKey: device.localKey,
|
|
model: device.model,
|
|
name: device.name,
|
|
icon: device.icon,
|
|
categoryName: device.categoryName,
|
|
type: device.type,
|
|
isOnline: device.isOnline,
|
|
status: device.status, // Make sure to keep the same status list
|
|
productName: device.productName,
|
|
timeZone: device.timeZone,
|
|
updateTime: device.updateTime,
|
|
uuid: device.uuid,
|
|
productUuid: device.productUuid,
|
|
productType: device.productType,
|
|
subspace: device.subspace,
|
|
toggleStatus: newToggleStatus,
|
|
);
|
|
break;
|
|
}
|
|
}
|
|
emit(GetDevicesSuccess(updatedDevices));
|
|
}
|
|
|
|
Future<void> threeGangToggle(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex == -1) {
|
|
throw Exception('Device not found');
|
|
}
|
|
final device = allDevices[deviceIndex];
|
|
final switches = ['switch_1', 'switch_2', 'switch_3'];
|
|
for (final switchCode in switches) {
|
|
final statusIndex =
|
|
device.status.indexWhere((s) => s.code == switchCode);
|
|
if (statusIndex != -1) {
|
|
final toggledValue = control.value;
|
|
final controlRequest = DeviceControlModel(
|
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
|
final response =
|
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
|
if (response['success'] != true) {
|
|
throw Exception('Failed to toggle $switchCode');
|
|
}
|
|
device.status[statusIndex].value = toggledValue;
|
|
}
|
|
}
|
|
final anySwitchOff = device.status.any(
|
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
|
);
|
|
device.toggleStatus = !anySwitchOff;
|
|
allDevices[deviceIndex] = device;
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} catch (failure) {
|
|
emit(DeviceControlError(failure.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> towGangToggle(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex == -1) {
|
|
throw Exception('Device not found');
|
|
}
|
|
final device = allDevices[deviceIndex];
|
|
final switches = [
|
|
'switch_1',
|
|
'switch_2',
|
|
];
|
|
for (final switchCode in switches) {
|
|
final statusIndex =
|
|
device.status.indexWhere((s) => s.code == switchCode);
|
|
if (statusIndex != -1) {
|
|
final toggledValue = control.value;
|
|
final controlRequest = DeviceControlModel(
|
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
|
final response =
|
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
|
|
|
device.status[statusIndex].value = response['result'];
|
|
}
|
|
}
|
|
final anySwitchOff = device.status.any(
|
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
|
);
|
|
device.toggleStatus = !anySwitchOff;
|
|
allDevices[deviceIndex] = device;
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} catch (failure) {
|
|
emit(DeviceControlError(failure.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> towGTGangToggle(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex == -1) {
|
|
throw Exception('Device not found');
|
|
}
|
|
final device = allDevices[deviceIndex];
|
|
final switches = [
|
|
'switch_1',
|
|
'switch_2',
|
|
];
|
|
for (final switchCode in switches) {
|
|
final statusIndex =
|
|
device.status.indexWhere((s) => s.code == switchCode);
|
|
if (statusIndex != -1) {
|
|
final toggledValue = control.value;
|
|
final controlRequest = DeviceControlModel(
|
|
code: switchCode, value: toggledValue, deviceId: deviceUuid);
|
|
final response =
|
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
|
|
|
device.status[statusIndex].value = response['result'];
|
|
}
|
|
}
|
|
final anySwitchOff = device.status.any(
|
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
|
);
|
|
device.toggleStatus = !anySwitchOff;
|
|
allDevices[deviceIndex] = device;
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} catch (failure) {
|
|
emit(DeviceControlError(failure.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> oneGangToggle(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex == -1) {
|
|
throw Exception('Device not found');
|
|
}
|
|
final device = allDevices[deviceIndex];
|
|
|
|
final statusIndex = device.status.indexWhere((s) => s.code == 'switch_1');
|
|
if (statusIndex != -1) {
|
|
final toggledValue = control.value;
|
|
final controlRequest = DeviceControlModel(
|
|
code: 'switch_1', value: toggledValue, deviceId: deviceUuid);
|
|
final response =
|
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
|
print(response);
|
|
if (response['result'] != true) {
|
|
throw Exception('Failed to toggle switch_1');
|
|
}
|
|
device.status[statusIndex].value = response['result'];
|
|
}
|
|
|
|
final anySwitchOff = device.status.any(
|
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
|
);
|
|
device.toggleStatus = !anySwitchOff;
|
|
allDevices[deviceIndex] = device;
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} catch (failure) {
|
|
emit(DeviceControlError(failure.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> oneGTGangToggle(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex == -1) {
|
|
throw Exception('Device not found');
|
|
}
|
|
final device = allDevices[deviceIndex];
|
|
|
|
final statusIndex = device.status.indexWhere((s) => s.code == 'switch_1');
|
|
if (statusIndex != -1) {
|
|
final currentValue = device.status[statusIndex].value ?? false;
|
|
final toggledValue = !currentValue;
|
|
final controlRequest = DeviceControlModel(
|
|
code: 'switch_1', value: toggledValue, deviceId: deviceUuid);
|
|
final response =
|
|
await DevicesAPI.controlDevice(controlRequest, deviceUuid);
|
|
if (response['result'] != true) {
|
|
throw Exception('Failed to toggle switch_1');
|
|
}
|
|
device.status[statusIndex].value = response['result'];
|
|
}
|
|
|
|
final anySwitchOff = device.status.any(
|
|
(s) => (s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
|
);
|
|
device.toggleStatus = !anySwitchOff;
|
|
allDevices[deviceIndex] = device;
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} catch (failure) {
|
|
emit(DeviceControlError(failure.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> deviceControl(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final response = await DevicesAPI.controlDevice(control, deviceUuid);
|
|
if (response['success'] == true) {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex != -1) {
|
|
final device = allDevices[deviceIndex];
|
|
final statusIndex =
|
|
device.status.indexWhere((s) => s.code == control.code);
|
|
if (statusIndex != -1) {
|
|
device.status[statusIndex].value = control.value;
|
|
}
|
|
final anySwitchOff = device.status.any(
|
|
(s) =>
|
|
(s.code?.startsWith('switch_') ?? false) && (s.value == false),
|
|
);
|
|
device.toggleStatus = !anySwitchOff;
|
|
allDevices[deviceIndex] = device;
|
|
}
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} else {
|
|
emit(DeviceControlError('Failed to control the device'));
|
|
}
|
|
} catch (failure) {
|
|
emit(DeviceControlError(failure.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> changeCurtainSwitch(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex == -1) {
|
|
throw Exception('Device not found');
|
|
}
|
|
final device = allDevices[deviceIndex];
|
|
final isOpen = control.value == "open";
|
|
final newValue = isOpen ? 0 : 100;
|
|
final response = await DevicesAPI.deviceBatchController(
|
|
code: 'percent_control',
|
|
devicesUuid: [deviceUuid],
|
|
value: newValue,
|
|
);
|
|
if (response['success'] == true) {
|
|
final statusIndex =
|
|
device.status.indexWhere((s) => s.code == 'percent_control');
|
|
if (statusIndex != -1) {
|
|
device.status[statusIndex].value = newValue;
|
|
}
|
|
allDevices[deviceIndex] = device;
|
|
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} else {
|
|
emit(DeviceControlError('Failed to toggle curtain.'));
|
|
}
|
|
} catch (error) {
|
|
emit(DeviceControlError(error.toString()));
|
|
}
|
|
}
|
|
|
|
Future<void> changeGarageSwitch(
|
|
DeviceControlModel control, String deviceUuid) async {
|
|
emit(SwitchControlLoading(code: control.code));
|
|
try {
|
|
final deviceIndex = allDevices.indexWhere((d) => d.uuid == deviceUuid);
|
|
if (deviceIndex == -1) {
|
|
throw Exception('Device not found');
|
|
}
|
|
final device = allDevices[deviceIndex];
|
|
final isOpen = control.value == "open";
|
|
final newValue = isOpen ? 0 : 100;
|
|
final response = await DevicesAPI.deviceBatchController(
|
|
code: 'percent_control',
|
|
devicesUuid: [deviceUuid],
|
|
value: newValue,
|
|
);
|
|
if (response['success'] == true) {
|
|
final statusIndex =
|
|
device.status.indexWhere((s) => s.code == 'percent_control');
|
|
if (statusIndex != -1) {
|
|
device.status[statusIndex].value = newValue;
|
|
}
|
|
allDevices[deviceIndex] = device;
|
|
emit(DeviceControlSuccess(code: control.code));
|
|
} else {
|
|
emit(DeviceControlError('Failed to toggle curtain.'));
|
|
}
|
|
} catch (error) {
|
|
emit(DeviceControlError(error.toString()));
|
|
}
|
|
}
|
|
}
|
|
|
|
enum LightMode {
|
|
Doze,
|
|
Relax,
|
|
Reading,
|
|
Energizing,
|
|
}
|