From b0854cec45a969cc463f5a7684393708777b30e8 Mon Sep 17 00:00:00 2001 From: mohammad Date: Sun, 25 Aug 2024 19:00:47 +0300 Subject: [PATCH] ac device --- .../device_managment/ac/bloc/ac_bloc.dart | 28 +++++++ .../device_managment/ac/bloc/ac_event.dart | 32 ++++++++ .../device_managment/ac/bloc/ac_state.dart | 76 +++++++++++++++++ .../ac/control_list/ac_toggle.dart | 43 ++++++++++ .../device_managment/ac/model/ac_model.dart | 81 +++++++++++++++++++ .../ac/view/ac_device_control.dart | 70 ++++++++++++++++ .../all_devices/helper/ac_helper.dart | 19 +++++ .../helper/route_controls_based_code.dart | 4 +- .../helper/living_room_helper.dart | 2 + lib/services/devices_mang_api.dart | 3 + lib/utils/constants/api_const.dart | 3 +- lib/utils/constants/const.dart | 4 + 12 files changed, 362 insertions(+), 3 deletions(-) create mode 100644 lib/pages/device_managment/ac/bloc/ac_bloc.dart create mode 100644 lib/pages/device_managment/ac/bloc/ac_event.dart create mode 100644 lib/pages/device_managment/ac/bloc/ac_state.dart create mode 100644 lib/pages/device_managment/ac/control_list/ac_toggle.dart create mode 100644 lib/pages/device_managment/ac/model/ac_model.dart create mode 100644 lib/pages/device_managment/ac/view/ac_device_control.dart create mode 100644 lib/pages/device_managment/all_devices/helper/ac_helper.dart diff --git a/lib/pages/device_managment/ac/bloc/ac_bloc.dart b/lib/pages/device_managment/ac/bloc/ac_bloc.dart new file mode 100644 index 00000000..86b48d52 --- /dev/null +++ b/lib/pages/device_managment/ac/bloc/ac_bloc.dart @@ -0,0 +1,28 @@ + +import 'dart:async'; +import 'package:bloc/bloc.dart'; +import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart'; +import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_state.dart'; +import 'package:syncrow_web/services/devices_mang_api.dart'; + + +class AcBloc extends Bloc { + + AcBloc() : super(AcsInitialState()) { + on(_onFetchAcStatus); + + } + + FutureOr _onFetchAcStatus( + AcFetchDeviceStatus event, Emitter emit) async { + emit(AcsLoadingState()); + try { + final status = + await DevicesManagementApi().getDeviceStatus(event.deviceId); + emit(ACStatusLoaded(status)); + } catch (e) { + emit(AcsFailedState( error: e.toString())); + } + } + +} diff --git a/lib/pages/device_managment/ac/bloc/ac_event.dart b/lib/pages/device_managment/ac/bloc/ac_event.dart new file mode 100644 index 00000000..cf1a1312 --- /dev/null +++ b/lib/pages/device_managment/ac/bloc/ac_event.dart @@ -0,0 +1,32 @@ + + +import 'package:equatable/equatable.dart'; + +sealed class AcsEvent extends Equatable { + const AcsEvent(); + + @override + List get props => []; +} + +class AcFetchDeviceStatus extends AcsEvent { + final String deviceId; + + const AcFetchDeviceStatus(this.deviceId); + + @override + List get props => [deviceId]; +} + +class AcControl extends AcsEvent { + final String deviceId; + final String code; + final bool value; + + const AcControl( + {required this.deviceId, required this.code, required this.value}); + + @override + List get props => [deviceId, code, value]; +} + diff --git a/lib/pages/device_managment/ac/bloc/ac_state.dart b/lib/pages/device_managment/ac/bloc/ac_state.dart new file mode 100644 index 00000000..0ebc523b --- /dev/null +++ b/lib/pages/device_managment/ac/bloc/ac_state.dart @@ -0,0 +1,76 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; +import 'package:syncrow_web/pages/visitor_password/model/device_model.dart'; + +abstract class AcsState extends Equatable { + const AcsState(); + + @override + List get props => []; +} + +class AcsInitialState extends AcsState {} + +class AcsLoadingState extends AcsState {} + + +class ACStatusLoaded extends AcsState { + final DeviceStatus status; + + const ACStatusLoaded(this.status); + + @override + List get props => [status]; +} + +class AcChangeLoading extends AcsState { + final AcStatusModel acStatusModel; + const AcChangeLoading({required this.acStatusModel}); + + @override + List get props => [acStatusModel]; +} + +class AcModifyingState extends AcsState { + final AcStatusModel acStatusModel; + const AcModifyingState({required this.acStatusModel}); + + @override + List get props => [acStatusModel]; +} + +class GetAcStatusState extends AcsState { + final AcStatusModel acStatusModel; + const GetAcStatusState({required this.acStatusModel}); + + @override + List get props => [acStatusModel]; +} + +class GetAllAcsStatusState extends AcsState { + final List allAcsStatues; + final List allAcs; + final bool allOn; + final bool allTempSame; + final int temp; + + const GetAllAcsStatusState( + {required this.allAcsStatues, + required this.allAcs, + required this.allOn, + required this.allTempSame, + required this.temp}); + + @override + List get props => [allAcsStatues, allAcs, allAcs, allTempSame, temp]; +} + +class AcsFailedState extends AcsState { + final String error; + + const AcsFailedState({required this.error}); + + @override + List get props => [error]; +} diff --git a/lib/pages/device_managment/ac/control_list/ac_toggle.dart b/lib/pages/device_managment/ac/control_list/ac_toggle.dart new file mode 100644 index 00000000..ffeba102 --- /dev/null +++ b/lib/pages/device_managment/ac/control_list/ac_toggle.dart @@ -0,0 +1,43 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/living_room_switch/bloc/living_room_bloc.dart'; + +class AcToggle extends StatelessWidget { + const AcToggle( + {super.key, + required this.value, + required this.code, + required this.deviceId}); + + final bool value; + final String code; + final String deviceId; + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ClipOval( + child: Transform.scale( + scale: .8, + child: CupertinoSwitch( + value:true, + onChanged: (value) { + + }, + applyTheme: true, + ), + ),), + ], + ), + + ], + ); + } +} diff --git a/lib/pages/device_managment/ac/model/ac_model.dart b/lib/pages/device_managment/ac/model/ac_model.dart new file mode 100644 index 00000000..566300ec --- /dev/null +++ b/lib/pages/device_managment/ac/model/ac_model.dart @@ -0,0 +1,81 @@ +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; +import 'package:syncrow_web/utils/constants/const.dart'; + +class AcStatusModel { + bool acSwitch; + String modeString; + int tempSet; + int currentTemp; + String fanSpeedsString; + bool childLock; + // late TempModes acMode; + // late FanSpeeds acFanSpeed; + + AcStatusModel( + {required this.acSwitch, + required this.modeString, + required this.tempSet, + required this.currentTemp, + required this.fanSpeedsString, + required this.childLock}) { + // acMode = getACMode(modeString); + // acFanSpeed = getFanSpeed(fanSpeedsString); + } + + factory AcStatusModel.fromJson(List jsonList) { + late bool _acSwitch; + late String _mode; + late int _tempSet; + late int _currentTemp; + late String _fanSpeeds; + late bool _childLock; + for (int i = 0; i < jsonList.length; i++) { + if (jsonList[i].code == 'switch') { + _acSwitch = jsonList[i].value ?? false; + } else if (jsonList[i].code == 'mode') { + _mode = jsonList[i].value ?? TempModes.cold; + } else if (jsonList[i].code == 'temp_set') { + _tempSet = jsonList[i].value ?? 210; + } else if (jsonList[i].code == 'temp_current') { + _currentTemp = jsonList[i].value ?? 210; + } else if (jsonList[i].code == 'level') { + _fanSpeeds = jsonList[i].value ?? 210; + } else if (jsonList[i].code == 'child_lock') { + _childLock = jsonList[i].value ?? false; + } + } + return AcStatusModel( + acSwitch: _acSwitch, + modeString: _mode, + tempSet: _tempSet, + currentTemp: _currentTemp, + fanSpeedsString: _fanSpeeds, + childLock: _childLock); + } + + static TempModes getACMode(String value) { + if (value == 'cold') { + return TempModes.cold; + } else if (value == 'hot') { + return TempModes.hot; + } else if (value == 'wind') { + return TempModes.wind; + } else { + return TempModes.cold; + } + } + + static FanSpeeds getFanSpeed(String value) { + if (value == 'low') { + return FanSpeeds.low; + } else if (value == 'middle') { + return FanSpeeds.middle; + } else if (value == 'high') { + return FanSpeeds.high; + } else if (value == 'auto') { + return FanSpeeds.auto; + } else { + return FanSpeeds.auto; + } + } +} diff --git a/lib/pages/device_managment/ac/view/ac_device_control.dart b/lib/pages/device_managment/ac/view/ac_device_control.dart new file mode 100644 index 00000000..937aaf5a --- /dev/null +++ b/lib/pages/device_managment/ac/view/ac_device_control.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart'; +import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart'; +import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_state.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; +import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; +import 'package:syncrow_web/pages/device_managment/living_room_switch/helper/living_room_helper.dart'; +import 'package:syncrow_web/utils/color_manager.dart'; + +class AcDeviceControl extends StatelessWidget with ACHelper { + const AcDeviceControl({super.key, required this.device}); + + final AllDevicesModel device; + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => + AcBloc()..add(AcFetchDeviceStatus(device.uuid!)), + child: BlocListener( + listener: (context, state) { + + }, + child: BlocBuilder( + builder: (context, state) { + if (state is AcsLoadingState) { + return const Center(child: CircularProgressIndicator()); + } else if (state is ACStatusLoaded) { + return _buildStatusControls(state.status.status); + } else { + return const Center(child: Text('Error fetching status')); + } + }, + ), + ), + ); + } + + Widget _buildStatusControls(List statuses) { + return GridView.builder( + padding: const EdgeInsets.symmetric(horizontal: 40), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + mainAxisExtent: 133, + crossAxisSpacing: 12, + mainAxisSpacing: 12, + ), + itemCount: statuses.length, + itemBuilder: (context, index) { + final status = statuses[index]; + + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: ColorsManager.greyColor.withOpacity(0.2), + border: Border.all(color: ColorsManager.boxDivider), + ), + padding: const EdgeInsets.all(16), + child: ACHelperControlWidgets( + value: status.value, + code: status.code, + deviceId: device.uuid!), + ); + }, + ); + } +} diff --git a/lib/pages/device_managment/all_devices/helper/ac_helper.dart b/lib/pages/device_managment/all_devices/helper/ac_helper.dart new file mode 100644 index 00000000..766f9c5a --- /dev/null +++ b/lib/pages/device_managment/all_devices/helper/ac_helper.dart @@ -0,0 +1,19 @@ + +import 'package:flutter/cupertino.dart'; +import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart'; + +mixin ACHelper { + Widget ACHelperControlWidgets( + {required bool value, required String code, required String deviceId}) { + switch (code) { + case 'switch_1': + return AcToggle(value: value, code: code, deviceId: deviceId); + case 'switch_2': + return SizedBox(); + case 'switch_3': + return SizedBox(); + default: + return const SizedBox(); + } + } +} diff --git a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart index a4556753..77b93c50 100644 --- a/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart +++ b/lib/pages/device_managment/all_devices/helper/route_controls_based_code.dart @@ -1,4 +1,6 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/device_managment/ac/view/ac_device_control.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart'; import 'package:syncrow_web/pages/device_managment/living_room_switch/view/living_room_device_control.dart'; @@ -16,7 +18,7 @@ mixin RouteControlsBasedCode { case 'Human Presence Sensor': return const SizedBox(); case 'Thermostat': - return const SizedBox(); + return AcDeviceControl(device: device); default: return const SizedBox(); } diff --git a/lib/pages/device_managment/living_room_switch/helper/living_room_helper.dart b/lib/pages/device_managment/living_room_switch/helper/living_room_helper.dart index 91159084..c97712cf 100644 --- a/lib/pages/device_managment/living_room_switch/helper/living_room_helper.dart +++ b/lib/pages/device_managment/living_room_switch/helper/living_room_helper.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart'; import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/cieling_light.dart'; import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/spot_light.dart'; import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/wall_light.dart'; @@ -18,3 +19,4 @@ mixin LivingRoomHelper { } } } + diff --git a/lib/services/devices_mang_api.dart b/lib/services/devices_mang_api.dart index 9346d7b1..5cdcd980 100644 --- a/lib/services/devices_mang_api.dart +++ b/lib/services/devices_mang_api.dart @@ -31,6 +31,7 @@ class DevicesManagementApi { path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid), showServerMessage: true, expectedResponseModel: (json) { + print('json==$json'); return DeviceStatus.fromJson(json); }, ); @@ -63,4 +64,6 @@ class DevicesManagementApi { return false; } } + + } diff --git a/lib/utils/constants/api_const.dart b/lib/utils/constants/api_const.dart index 6e92445c..27ca2a3e 100644 --- a/lib/utils/constants/api_const.dart +++ b/lib/utils/constants/api_const.dart @@ -29,8 +29,7 @@ abstract class ApiEndpoints { ////// Devices Management //////////////// static const String getAllDevices = '$baseUrl/device'; - static const String getDeviceStatus = - '$baseUrl/device/{uuid}/functions/status'; + static const String getDeviceStatus = '$baseUrl/device/{uuid}/functions/status'; static const String deviceControl = '$baseUrl/device/{uuid}/control'; } diff --git a/lib/utils/constants/const.dart b/lib/utils/constants/const.dart index 09f44f0f..4ca37d9b 100644 --- a/lib/utils/constants/const.dart +++ b/lib/utils/constants/const.dart @@ -93,3 +93,7 @@ extension AccessStatusExtension on AccessStatus { } } } + +enum TempModes { hot, cold, wind } + +enum FanSpeeds { auto, low, middle, high }