ac device

This commit is contained in:
mohammad
2024-08-25 19:00:47 +03:00
parent 203627fb31
commit b0854cec45
12 changed files with 362 additions and 3 deletions

View File

@ -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<AcsEvent, AcsState> {
AcBloc() : super(AcsInitialState()) {
on<AcFetchDeviceStatus>(_onFetchAcStatus);
}
FutureOr<void> _onFetchAcStatus(
AcFetchDeviceStatus event, Emitter<AcsState> emit) async {
emit(AcsLoadingState());
try {
final status =
await DevicesManagementApi().getDeviceStatus(event.deviceId);
emit(ACStatusLoaded(status));
} catch (e) {
emit(AcsFailedState( error: e.toString()));
}
}
}

View File

@ -0,0 +1,32 @@
import 'package:equatable/equatable.dart';
sealed class AcsEvent extends Equatable {
const AcsEvent();
@override
List<Object> get props => [];
}
class AcFetchDeviceStatus extends AcsEvent {
final String deviceId;
const AcFetchDeviceStatus(this.deviceId);
@override
List<Object> 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<Object> get props => [deviceId, code, value];
}

View File

@ -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<Object> get props => [];
}
class AcsInitialState extends AcsState {}
class AcsLoadingState extends AcsState {}
class ACStatusLoaded extends AcsState {
final DeviceStatus status;
const ACStatusLoaded(this.status);
@override
List<Object> get props => [status];
}
class AcChangeLoading extends AcsState {
final AcStatusModel acStatusModel;
const AcChangeLoading({required this.acStatusModel});
@override
List<Object> get props => [acStatusModel];
}
class AcModifyingState extends AcsState {
final AcStatusModel acStatusModel;
const AcModifyingState({required this.acStatusModel});
@override
List<Object> get props => [acStatusModel];
}
class GetAcStatusState extends AcsState {
final AcStatusModel acStatusModel;
const GetAcStatusState({required this.acStatusModel});
@override
List<Object> get props => [acStatusModel];
}
class GetAllAcsStatusState extends AcsState {
final List<AcStatusModel> allAcsStatues;
final List<DeviceModel> 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<Object> get props => [allAcsStatues, allAcs, allAcs, allTempSame, temp];
}
class AcsFailedState extends AcsState {
final String error;
const AcsFailedState({required this.error});
@override
List<Object> get props => [error];
}

View File

@ -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,
),
),),
],
),
],
);
}
}

View File

@ -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<Status> 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;
}
}
}

View File

@ -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<AcBloc, AcsState>(
listener: (context, state) {
},
child: BlocBuilder<AcBloc, AcsState>(
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<Status> 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!),
);
},
);
}
}

View File

@ -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();
}
}
}

View File

@ -1,4 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.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/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/device_managment/living_room_switch/view/living_room_device_control.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': case 'Human Presence Sensor':
return const SizedBox(); return const SizedBox();
case 'Thermostat': case 'Thermostat':
return const SizedBox(); return AcDeviceControl(device: device);
default: default:
return const SizedBox(); return const SizedBox();
} }

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; 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/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/spot_light.dart';
import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/wall_light.dart'; import 'package:syncrow_web/pages/device_managment/living_room_switch/control_list/wall_light.dart';
@ -18,3 +19,4 @@ mixin LivingRoomHelper {
} }
} }
} }

View File

@ -31,6 +31,7 @@ class DevicesManagementApi {
path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid), path: ApiEndpoints.getDeviceStatus.replaceAll('{uuid}', uuid),
showServerMessage: true, showServerMessage: true,
expectedResponseModel: (json) { expectedResponseModel: (json) {
print('json==$json');
return DeviceStatus.fromJson(json); return DeviceStatus.fromJson(json);
}, },
); );
@ -63,4 +64,6 @@ class DevicesManagementApi {
return false; return false;
} }
} }
} }

View File

@ -29,8 +29,7 @@ abstract class ApiEndpoints {
////// Devices Management //////////////// ////// Devices Management ////////////////
static const String getAllDevices = '$baseUrl/device'; static const String getAllDevices = '$baseUrl/device';
static const String getDeviceStatus = static const String getDeviceStatus = '$baseUrl/device/{uuid}/functions/status';
'$baseUrl/device/{uuid}/functions/status';
static const String deviceControl = '$baseUrl/device/{uuid}/control'; static const String deviceControl = '$baseUrl/device/{uuid}/control';
} }

View File

@ -93,3 +93,7 @@ extension AccessStatusExtension on AccessStatus {
} }
} }
} }
enum TempModes { hot, cold, wind }
enum FanSpeeds { auto, low, middle, high }