mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
changing ac bloc
This commit is contained in:
@ -1,16 +1,31 @@
|
||||
|
||||
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/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/services/devices_mang_api.dart';
|
||||
|
||||
|
||||
class AcBloc extends Bloc<AcsEvent, AcsState> {
|
||||
AcStatusModel deviceStatus = AcStatusModel(
|
||||
uuid: '',
|
||||
acSwitch: true,
|
||||
modeString: 'hot',
|
||||
tempSet: 300,
|
||||
currentTemp: 315,
|
||||
fanSpeedsString: 'low',
|
||||
childLock: false,
|
||||
);
|
||||
|
||||
AcBloc() : super(AcsInitialState()) {
|
||||
on<AcFetchDeviceStatus>(_onFetchAcStatus);
|
||||
|
||||
on<AcControl>(_onAcControl);
|
||||
on<AcSwitch>(_changeAcSwitch);
|
||||
on<IncreaseCoolToTemp>(_increaseCoolTo);
|
||||
on<DecreaseCoolToTemp>(_decreaseCoolTo);
|
||||
on<ChangeLock>(_changeLockValue);
|
||||
on<ChangeAcMode>(_changeAcMode);
|
||||
on<ChangeFanSpeed>(_changeFanSpeed);
|
||||
}
|
||||
|
||||
FutureOr<void> _onFetchAcStatus(
|
||||
@ -18,11 +33,121 @@ class AcBloc extends Bloc<AcsEvent, AcsState> {
|
||||
emit(AcsLoadingState());
|
||||
try {
|
||||
final status =
|
||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||
emit(ACStatusLoaded(status));
|
||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||
deviceStatus = AcStatusModel.fromJson(status.productUuid, status.status);
|
||||
emit(ACStatusLoaded(deviceStatus));
|
||||
} catch (e) {
|
||||
emit(AcsFailedState( error: e.toString()));
|
||||
emit(AcsFailedState(error: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _onAcControl(AcControl event, Emitter<AcsState> emit) async {
|
||||
final oldValue = _getValueByCode(event.code);
|
||||
|
||||
_updateLocalValue(event.code, event.value);
|
||||
emit(ACStatusLoaded(deviceStatus));
|
||||
|
||||
try {
|
||||
final status = Status(code: event.code, value: event.value);
|
||||
final response =
|
||||
await DevicesManagementApi().deviceControl(event.deviceId, status);
|
||||
|
||||
if (!response) {
|
||||
_updateLocalValue(event.code, oldValue);
|
||||
emit(ACStatusLoaded(deviceStatus));
|
||||
emit(AcsFailedState(error: 'Failed to control the device.'));
|
||||
}
|
||||
} catch (e) {
|
||||
_updateLocalValue(event.code, oldValue);
|
||||
emit(ACStatusLoaded(deviceStatus));
|
||||
emit(AcsFailedState(error: 'Error controlling the device: $e'));
|
||||
}
|
||||
}
|
||||
|
||||
void _updateLocalValue(String code, dynamic value) {
|
||||
switch (code) {
|
||||
case 'switch':
|
||||
deviceStatus.acSwitch = value;
|
||||
break;
|
||||
case 'temp_set':
|
||||
deviceStatus.tempSet = value;
|
||||
break;
|
||||
case 'mode':
|
||||
deviceStatus.modeString = value;
|
||||
deviceStatus.acMode = AcStatusModel.getACMode(value);
|
||||
break;
|
||||
case 'level':
|
||||
deviceStatus.fanSpeedsString = value;
|
||||
deviceStatus.acFanSpeed = AcStatusModel.getFanSpeed(value);
|
||||
break;
|
||||
case 'child_lock':
|
||||
deviceStatus.childLock = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dynamic _getValueByCode(String code) {
|
||||
switch (code) {
|
||||
case 'switch':
|
||||
return deviceStatus.acSwitch;
|
||||
case 'temp_set':
|
||||
return deviceStatus.tempSet;
|
||||
case 'mode':
|
||||
return deviceStatus.modeString;
|
||||
case 'level':
|
||||
return deviceStatus.fanSpeedsString;
|
||||
case 'child_lock':
|
||||
return deviceStatus.childLock;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _changeAcSwitch(AcSwitch event, Emitter<AcsState> emit) async {
|
||||
final newValue = !event.acSwitch;
|
||||
add(AcControl(deviceId: event.deviceId, code: 'switch', value: newValue));
|
||||
}
|
||||
|
||||
FutureOr<void> _increaseCoolTo(
|
||||
IncreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
||||
final newValue = (event.value * 10).toInt() + 5;
|
||||
if (_isValidTemperature(newValue)) {
|
||||
add(AcControl(
|
||||
deviceId: event.deviceId, code: 'temp_set', value: newValue));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _decreaseCoolTo(
|
||||
DecreaseCoolToTemp event, Emitter<AcsState> emit) async {
|
||||
final newValue = (event.value * 10).toInt() - 5;
|
||||
if (_isValidTemperature(newValue)) {
|
||||
add(AcControl(
|
||||
deviceId: event.deviceId, code: 'temp_set', value: newValue));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _changeLockValue(
|
||||
ChangeLock event, Emitter<AcsState> emit) async {
|
||||
final newValue = !event.lockBool;
|
||||
add(AcControl(
|
||||
deviceId: event.deviceId, code: 'child_lock', value: newValue));
|
||||
}
|
||||
|
||||
FutureOr<void> _changeAcMode(
|
||||
ChangeAcMode event, Emitter<AcsState> emit) async {
|
||||
final newValue = AcStatusModel.getACMode(event.tempModes.name);
|
||||
add(AcControl(deviceId: event.deviceId, code: 'mode', value: newValue));
|
||||
}
|
||||
|
||||
FutureOr<void> _changeFanSpeed(
|
||||
ChangeFanSpeed event, Emitter<AcsState> emit) async {
|
||||
final newValue = AcStatusModel.getFanSpeed(event.fanSpeeds.name);
|
||||
add(AcControl(deviceId: event.deviceId, code: 'level', value: newValue));
|
||||
}
|
||||
|
||||
bool _isValidTemperature(int value) {
|
||||
return value >= 200 && value <= 300;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
|
||||
|
||||
sealed class AcsEvent extends Equatable {
|
||||
const AcsEvent();
|
||||
@ -21,12 +20,74 @@ class AcFetchDeviceStatus extends AcsEvent {
|
||||
class AcControl extends AcsEvent {
|
||||
final String deviceId;
|
||||
final String code;
|
||||
final bool value;
|
||||
final dynamic value;
|
||||
|
||||
const AcControl(
|
||||
{required this.deviceId, required this.code, required this.value});
|
||||
const AcControl({
|
||||
required this.deviceId,
|
||||
required this.code,
|
||||
required this.value,
|
||||
});
|
||||
|
||||
@override
|
||||
List<Object> get props => [deviceId, code, value];
|
||||
}
|
||||
|
||||
class AcSwitch extends AcsEvent {
|
||||
final bool acSwitch;
|
||||
final String deviceId;
|
||||
|
||||
const AcSwitch({required this.acSwitch, required this.deviceId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [acSwitch, deviceId];
|
||||
}
|
||||
|
||||
class IncreaseCoolToTemp extends AcsEvent {
|
||||
final double value;
|
||||
final String deviceId;
|
||||
|
||||
const IncreaseCoolToTemp({required this.value, required this.deviceId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [value, deviceId];
|
||||
}
|
||||
|
||||
class DecreaseCoolToTemp extends AcsEvent {
|
||||
final double value;
|
||||
final String deviceId;
|
||||
|
||||
const DecreaseCoolToTemp({required this.value, required this.deviceId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [value, deviceId];
|
||||
}
|
||||
|
||||
class ChangeLock extends AcsEvent {
|
||||
final bool lockBool;
|
||||
final String deviceId;
|
||||
|
||||
const ChangeLock({required this.lockBool, required this.deviceId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [lockBool, deviceId];
|
||||
}
|
||||
|
||||
class ChangeAcMode extends AcsEvent {
|
||||
final TempModes tempModes;
|
||||
final String deviceId;
|
||||
|
||||
const ChangeAcMode({required this.tempModes, required this.deviceId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [tempModes, deviceId];
|
||||
}
|
||||
|
||||
class ChangeFanSpeed extends AcsEvent {
|
||||
final FanSpeeds fanSpeeds;
|
||||
final String deviceId;
|
||||
|
||||
const ChangeFanSpeed({required this.fanSpeeds, required this.deviceId});
|
||||
|
||||
@override
|
||||
List<Object> get props => [fanSpeeds, deviceId];
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
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();
|
||||
@ -14,9 +12,8 @@ class AcsInitialState extends AcsState {}
|
||||
|
||||
class AcsLoadingState extends AcsState {}
|
||||
|
||||
|
||||
class ACStatusLoaded extends AcsState {
|
||||
final DeviceStatus status;
|
||||
final AcStatusModel status;
|
||||
|
||||
const ACStatusLoaded(this.status);
|
||||
|
||||
@ -24,46 +21,49 @@ class ACStatusLoaded extends AcsState {
|
||||
List<Object> get props => [status];
|
||||
}
|
||||
|
||||
class AcChangeLoading extends AcsState {
|
||||
final AcStatusModel acStatusModel;
|
||||
const AcChangeLoading({required this.acStatusModel});
|
||||
class AcSwitchChanged extends AcsState {
|
||||
final bool acSwitch;
|
||||
|
||||
const AcSwitchChanged(this.acSwitch);
|
||||
|
||||
@override
|
||||
List<Object> get props => [acStatusModel];
|
||||
List<Object> get props => [acSwitch];
|
||||
}
|
||||
|
||||
class AcModifyingState extends AcsState {
|
||||
final AcStatusModel acStatusModel;
|
||||
const AcModifyingState({required this.acStatusModel});
|
||||
class AcTempChanged extends AcsState {
|
||||
final double tempSet;
|
||||
|
||||
const AcTempChanged(this.tempSet);
|
||||
|
||||
@override
|
||||
List<Object> get props => [acStatusModel];
|
||||
List<Object> get props => [tempSet];
|
||||
}
|
||||
|
||||
class GetAcStatusState extends AcsState {
|
||||
final AcStatusModel acStatusModel;
|
||||
const GetAcStatusState({required this.acStatusModel});
|
||||
class AcModeChanged extends AcsState {
|
||||
final TempModes mode;
|
||||
|
||||
const AcModeChanged(this.mode);
|
||||
|
||||
@override
|
||||
List<Object> get props => [acStatusModel];
|
||||
List<Object> get props => [mode];
|
||||
}
|
||||
|
||||
class GetAllAcsStatusState extends AcsState {
|
||||
final List<AcStatusModel> allAcsStatues;
|
||||
final List<DeviceModel> allAcs;
|
||||
final bool allOn;
|
||||
final bool allTempSame;
|
||||
final int temp;
|
||||
class AcFanSpeedChanged extends AcsState {
|
||||
final FanSpeeds fanSpeed;
|
||||
|
||||
const GetAllAcsStatusState(
|
||||
{required this.allAcsStatues,
|
||||
required this.allAcs,
|
||||
required this.allOn,
|
||||
required this.allTempSame,
|
||||
required this.temp});
|
||||
const AcFanSpeedChanged(this.fanSpeed);
|
||||
|
||||
@override
|
||||
List<Object> get props => [allAcsStatues, allAcs, allAcs, allTempSame, temp];
|
||||
List<Object> get props => [fanSpeed];
|
||||
}
|
||||
|
||||
class AcLockChanged extends AcsState {
|
||||
final bool lock;
|
||||
|
||||
const AcLockChanged(this.lock);
|
||||
|
||||
@override
|
||||
List<Object> get props => [lock];
|
||||
}
|
||||
|
||||
class AcsFailedState extends AcsState {
|
||||
|
82
lib/pages/device_managment/ac/control_list/ac_mode.dart
Normal file
82
lib/pages/device_managment/ac/control_list/ac_mode.dart
Normal file
@ -0,0 +1,82 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.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';
|
||||
|
||||
class AcMode extends StatelessWidget {
|
||||
const AcMode({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.code,
|
||||
required this.deviceId,
|
||||
});
|
||||
|
||||
final TempModes value;
|
||||
final String code;
|
||||
final String deviceId;
|
||||
|
||||
void _onModeSelected(BuildContext context, TempModes mode) {
|
||||
context.read<AcBloc>().add(
|
||||
ChangeAcMode(tempModes: mode, deviceId: deviceId),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
_buildIconContainer(context, TempModes.cold, Assets.freezing,
|
||||
value == TempModes.cold),
|
||||
_buildIconContainer(
|
||||
context, TempModes.hot, Assets.acSun, value == TempModes.hot),
|
||||
_buildIconContainer(context, TempModes.wind, Assets.acAirConditioner,
|
||||
value == TempModes.wind),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildIconContainer(
|
||||
BuildContext context, TempModes mode, String assetPath, bool isSelected) {
|
||||
return Flexible(
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
_onModeSelected(context, mode);
|
||||
},
|
||||
child: Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: ColorsManager.whiteColors,
|
||||
border: Border.all(
|
||||
color: isSelected ? Colors.blue : Colors.transparent,
|
||||
width: 2.0,
|
||||
),
|
||||
),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: ClipOval(
|
||||
child: SvgPicture.asset(
|
||||
assetPath,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,43 +1,85 @@
|
||||
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';
|
||||
import 'package:flutter_svg/flutter_svg.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/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
class AcToggle extends StatelessWidget {
|
||||
const AcToggle(
|
||||
{super.key,
|
||||
required this.value,
|
||||
required this.code,
|
||||
required this.deviceId});
|
||||
const AcToggle({
|
||||
super.key,
|
||||
required this.value,
|
||||
required this.code,
|
||||
required this.deviceId,
|
||||
this.icon,
|
||||
this.description,
|
||||
});
|
||||
|
||||
final bool value;
|
||||
final String code;
|
||||
final String deviceId;
|
||||
final String? icon;
|
||||
final String? description;
|
||||
|
||||
@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,
|
||||
),
|
||||
),),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
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: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
ClipOval(
|
||||
child: Container(
|
||||
color: ColorsManager.whiteColors,
|
||||
child: SvgPicture.asset(
|
||||
icon ?? Assets.acDevice,
|
||||
width: 60,
|
||||
height: 60,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
)),
|
||||
SizedBox(
|
||||
height: 20,
|
||||
width: 35,
|
||||
child: CupertinoSwitch(
|
||||
activeColor: ColorsManager.dialogBlueTitle,
|
||||
value: value,
|
||||
onChanged: (newValue) {
|
||||
context.read<AcBloc>().add(
|
||||
AcControl(
|
||||
deviceId: deviceId,
|
||||
code: code,
|
||||
value: newValue,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
Center(
|
||||
child: Text(
|
||||
description ?? 'ThermoState',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
134
lib/pages/device_managment/ac/control_list/current_temp.dart
Normal file
134
lib/pages/device_managment/ac/control_list/current_temp.dart
Normal file
@ -0,0 +1,134 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_event.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/celciuse_symbol.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/shared/increament_decreament.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/bloc/ac_bloc.dart';
|
||||
|
||||
class CurrentTemp extends StatefulWidget {
|
||||
const CurrentTemp({
|
||||
super.key,
|
||||
required this.code,
|
||||
required this.deviceId,
|
||||
required this.currentTemp,
|
||||
required this.tempSet,
|
||||
});
|
||||
|
||||
final String code;
|
||||
final String deviceId;
|
||||
final int currentTemp;
|
||||
final int tempSet;
|
||||
|
||||
@override
|
||||
State<CurrentTemp> createState() => _CurrentTempState();
|
||||
}
|
||||
|
||||
class _CurrentTempState extends State<CurrentTemp> {
|
||||
late double _adjustedValue;
|
||||
Timer? _debounce;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_adjustedValue = _initialAdjustedValue(widget.tempSet);
|
||||
}
|
||||
|
||||
double _initialAdjustedValue(dynamic value) {
|
||||
if (value is int || value is double) {
|
||||
double doubleValue = value.toDouble();
|
||||
return doubleValue > 99 ? doubleValue / 10 : doubleValue;
|
||||
} else {
|
||||
throw ArgumentError('Invalid value type: Expected int or double');
|
||||
}
|
||||
}
|
||||
|
||||
void _onValueChanged(double newValue) {
|
||||
if (_debounce?.isActive ?? false) {
|
||||
_debounce?.cancel();
|
||||
}
|
||||
_debounce = Timer(const Duration(milliseconds: 500), () {
|
||||
context.read<AcBloc>().add(
|
||||
AcControl(
|
||||
deviceId: widget.deviceId,
|
||||
code: widget.code,
|
||||
value: newValue * 10,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_debounce?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Current Temperature',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Colors.grey),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
(widget.currentTemp > 99
|
||||
? widget.currentTemp / 10
|
||||
: widget.currentTemp)
|
||||
.toString(),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodySmall!
|
||||
.copyWith(color: Colors.grey),
|
||||
),
|
||||
const CelsiusSymbol(
|
||||
color: Colors.grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
IncrementDecrementWidget(
|
||||
value: _adjustedValue.toString(),
|
||||
description: '°C',
|
||||
descriptionColor: ColorsManager.dialogBlueTitle,
|
||||
onIncrement: () {
|
||||
setState(() {
|
||||
_adjustedValue++;
|
||||
});
|
||||
_onValueChanged(_adjustedValue);
|
||||
},
|
||||
onDecrement: () {
|
||||
setState(() {
|
||||
_adjustedValue--;
|
||||
});
|
||||
_onValueChanged(_adjustedValue);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
35
lib/pages/device_managment/ac/helper/ac_helper.dart
Normal file
35
lib/pages/device_managment/ac/helper/ac_helper.dart
Normal file
@ -0,0 +1,35 @@
|
||||
// import 'package:flutter/cupertino.dart';
|
||||
// import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_mode.dart';
|
||||
// import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart';
|
||||
// import 'package:syncrow_web/pages/device_managment/ac/control_list/current_temp.dart';
|
||||
// import 'package:syncrow_web/utils/constants/assets.dart';
|
||||
|
||||
// mixin ACHelper {
|
||||
// Widget acHelperControlWidgets({
|
||||
// required dynamic value,
|
||||
// required String code,
|
||||
// required String deviceId,
|
||||
// }) {
|
||||
// switch (code) {
|
||||
// case 'switch':
|
||||
// return AcToggle(value: value, code: code, deviceId: deviceId);
|
||||
// case 'temp_current':
|
||||
// return CurrentTemp(value: value, code: 'temp_set', deviceId: deviceId);
|
||||
// case 'temp_set':
|
||||
// return SizedBox();
|
||||
// case 'mode':
|
||||
// return AcMode(value: value, code: code, deviceId: deviceId);
|
||||
// case 'level':
|
||||
// return SizedBox();
|
||||
// case 'child_lock':
|
||||
// return AcToggle(
|
||||
// value: value,
|
||||
// code: code,
|
||||
// deviceId: deviceId,
|
||||
// icon: Assets.childLock,
|
||||
// description: 'Child Lock');
|
||||
// default:
|
||||
// return const SizedBox();
|
||||
// }
|
||||
// }
|
||||
// }
|
@ -1,28 +1,33 @@
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
import 'package:syncrow_web/utils/constants/const.dart';
|
||||
|
||||
enum TempModes { hot, cold, wind }
|
||||
|
||||
enum FanSpeeds { auto, low, middle, high }
|
||||
|
||||
class AcStatusModel {
|
||||
String uuid;
|
||||
bool acSwitch;
|
||||
String modeString;
|
||||
int tempSet;
|
||||
int currentTemp;
|
||||
String fanSpeedsString;
|
||||
bool childLock;
|
||||
// late TempModes acMode;
|
||||
// late FanSpeeds acFanSpeed;
|
||||
late TempModes acMode;
|
||||
late FanSpeeds acFanSpeed;
|
||||
|
||||
AcStatusModel(
|
||||
{required this.acSwitch,
|
||||
{required this.uuid,
|
||||
required this.acSwitch,
|
||||
required this.modeString,
|
||||
required this.tempSet,
|
||||
required this.currentTemp,
|
||||
required this.fanSpeedsString,
|
||||
required this.childLock}) {
|
||||
// acMode = getACMode(modeString);
|
||||
// acFanSpeed = getFanSpeed(fanSpeedsString);
|
||||
acMode = getACMode(modeString);
|
||||
acFanSpeed = getFanSpeed(fanSpeedsString);
|
||||
}
|
||||
|
||||
factory AcStatusModel.fromJson(List<Status> jsonList) {
|
||||
factory AcStatusModel.fromJson(String id, List<Status> jsonList) {
|
||||
late bool _acSwitch;
|
||||
late String _mode;
|
||||
late int _tempSet;
|
||||
@ -45,6 +50,7 @@ class AcStatusModel {
|
||||
}
|
||||
}
|
||||
return AcStatusModel(
|
||||
uuid: id,
|
||||
acSwitch: _acSwitch,
|
||||
modeString: _mode,
|
||||
tempSet: _tempSet,
|
||||
|
@ -3,68 +3,72 @@ 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/helper/ac_helper.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_mode.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/control_list/ac_toggle.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/control_list/current_temp.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/ac/model/ac_model.dart';
|
||||
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
|
||||
|
||||
class AcDeviceControl extends StatelessWidget with ACHelper {
|
||||
class AcDeviceControl extends StatelessWidget with HelperResponsiveLayout {
|
||||
const AcDeviceControl({super.key, required this.device});
|
||||
|
||||
final AllDevicesModel device;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isLarge = isLargeScreenSize(context);
|
||||
final isMedium = isMediumScreenSize(context);
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
AcBloc()..add(AcFetchDeviceStatus(device.uuid!)),
|
||||
child: BlocListener<AcBloc, AcsState>(
|
||||
listener: (context, state) {
|
||||
|
||||
create: (context) => AcBloc()..add(AcFetchDeviceStatus(device.uuid!)),
|
||||
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, isLarge, isMedium);
|
||||
} else {
|
||||
return const Center(child: Text('Error fetching status'));
|
||||
}
|
||||
},
|
||||
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),
|
||||
Widget _buildStatusControls(
|
||||
AcStatusModel statuses, bool isLarge, bool isMedium) {
|
||||
return GridView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 3,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: isLarge
|
||||
? 3
|
||||
: isMedium
|
||||
? 2
|
||||
: 1,
|
||||
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!),
|
||||
);
|
||||
},
|
||||
children: [
|
||||
AcToggle(
|
||||
value: statuses.acSwitch,
|
||||
code: 'switch',
|
||||
deviceId: statuses.uuid,
|
||||
),
|
||||
AcMode(
|
||||
value: statuses.acMode,
|
||||
code: 'mode',
|
||||
deviceId: statuses.uuid,
|
||||
),
|
||||
CurrentTemp(
|
||||
currentTemp: statuses.currentTemp,
|
||||
tempSet: statuses.tempSet,
|
||||
code: 'temp_set',
|
||||
deviceId: statuses.uuid,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
@ -35,9 +35,12 @@ class LivingRoomBloc extends Bloc<LivingRoomEvent, LivingRoomState> {
|
||||
await DevicesManagementApi().deviceControl(event.deviceId, status);
|
||||
|
||||
if (response) {
|
||||
emit(LivingRoomControlSuccess());
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
add(LivingRoomFetchDeviceStatus(event.deviceId));
|
||||
final newStatus =
|
||||
await DevicesManagementApi().getDeviceStatus(event.deviceId);
|
||||
emit(LivingRoomDeviceStatusLoaded(newStatus));
|
||||
} else {
|
||||
emit(const LivingRoomControlError('Failed to control the device.'));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(LivingRoomControlError('Error controlling the device: $e'));
|
||||
|
@ -41,6 +41,7 @@ class CeilingLight extends StatelessWidget {
|
||||
width: 35,
|
||||
child: CupertinoSwitch(
|
||||
value: value,
|
||||
activeColor: ColorsManager.dialogBlueTitle,
|
||||
onChanged: (newValue) {
|
||||
context.read<LivingRoomBloc>().add(
|
||||
LivingRoomControl(
|
||||
|
@ -41,6 +41,7 @@ class SpotLight extends StatelessWidget {
|
||||
width: 35,
|
||||
child: CupertinoSwitch(
|
||||
value: value,
|
||||
activeColor: ColorsManager.dialogBlueTitle,
|
||||
onChanged: (newValue) {
|
||||
context.read<LivingRoomBloc>().add(
|
||||
LivingRoomControl(
|
||||
|
@ -41,6 +41,7 @@ class WallLight extends StatelessWidget {
|
||||
width: 35,
|
||||
child: CupertinoSwitch(
|
||||
value: value,
|
||||
activeColor: ColorsManager.dialogBlueTitle,
|
||||
onChanged: (newValue) {
|
||||
context.read<LivingRoomBloc>().add(
|
||||
LivingRoomControl(
|
||||
|
@ -1,5 +1,4 @@
|
||||
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';
|
||||
|
@ -16,25 +16,19 @@ class LivingRoomDeviceControl extends StatelessWidget with LivingRoomHelper {
|
||||
return BlocProvider(
|
||||
create: (context) =>
|
||||
LivingRoomBloc()..add(LivingRoomFetchDeviceStatus(device.uuid!)),
|
||||
child: BlocListener<LivingRoomBloc, LivingRoomState>(
|
||||
listener: (context, state) {
|
||||
if (state is LivingRoomControlSuccess) {
|
||||
context
|
||||
.read<LivingRoomBloc>()
|
||||
.add(LivingRoomFetchDeviceStatus(device.uuid!));
|
||||
child: BlocBuilder<LivingRoomBloc, LivingRoomState>(
|
||||
builder: (context, state) {
|
||||
if (state is LivingRoomDeviceStatusLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is LivingRoomDeviceStatusLoaded) {
|
||||
return _buildStatusControls(state.status.status);
|
||||
} else if ((state is LivingRoomDeviceManagementError) ||
|
||||
(state is LivingRoomControlError)) {
|
||||
return const Center(child: Text('Error fetching status'));
|
||||
} else {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
},
|
||||
child: BlocBuilder<LivingRoomBloc, LivingRoomState>(
|
||||
builder: (context, state) {
|
||||
if (state is LivingRoomDeviceStatusLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
} else if (state is LivingRoomDeviceStatusLoaded) {
|
||||
return _buildStatusControls(state.status.status);
|
||||
} else {
|
||||
return const Center(child: Text('Error fetching status'));
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -50,7 +44,7 @@ class LivingRoomDeviceControl extends StatelessWidget with LivingRoomHelper {
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisSpacing: 12,
|
||||
),
|
||||
itemCount: statuses.length,
|
||||
itemCount: 3,
|
||||
itemBuilder: (context, index) {
|
||||
final status = statuses[index];
|
||||
|
||||
|
17
lib/pages/device_managment/shared/celciuse_symbol.dart
Normal file
17
lib/pages/device_managment/shared/celciuse_symbol.dart
Normal file
@ -0,0 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CelsiusSymbol extends StatelessWidget {
|
||||
const CelsiusSymbol({this.color, super.key});
|
||||
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(
|
||||
'°C',
|
||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||
color: color,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
|
||||
const SizedBox(height: 20),
|
||||
//// BUILD DEVICE CONTROLS
|
||||
///
|
||||
//// ROUTE TO SPECIFIC CONTROL VIEW BASED ON DEVICE CATEGORY
|
||||
//// ROUTE TO SPECIFIC CONTROL VIEW BASED ON DEVICE CATEGORY
|
||||
routeControlsWidgets(device: device),
|
||||
],
|
||||
),
|
||||
@ -56,7 +56,7 @@ class DeviceControlDialog extends StatelessWidget with RouteControlsBasedCode {
|
||||
|
||||
Widget _buildDeviceInfoSection() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 40, horizontal: 50),
|
||||
padding: const EdgeInsets.symmetric(vertical: 50, horizontal: 50),
|
||||
child: Table(
|
||||
children: [
|
||||
TableRow(
|
||||
|
@ -6,6 +6,7 @@ class IncrementDecrementWidget extends StatelessWidget {
|
||||
final String description;
|
||||
final VoidCallback onIncrement;
|
||||
final VoidCallback onDecrement;
|
||||
final Color? descriptionColor;
|
||||
|
||||
const IncrementDecrementWidget({
|
||||
super.key,
|
||||
@ -13,6 +14,7 @@ class IncrementDecrementWidget extends StatelessWidget {
|
||||
required this.description,
|
||||
required this.onIncrement,
|
||||
required this.onDecrement,
|
||||
this.descriptionColor,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -22,18 +24,20 @@ class IncrementDecrementWidget extends StatelessWidget {
|
||||
children: [
|
||||
Material(
|
||||
type: MaterialType.transparency,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: InkWell(
|
||||
splashColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent,
|
||||
onTap: onDecrement,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
Icons.remove,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 32,
|
||||
child: Flexible(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: InkWell(
|
||||
splashColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent,
|
||||
onTap: onDecrement,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
Icons.remove,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -53,9 +57,9 @@ class IncrementDecrementWidget extends StatelessWidget {
|
||||
),
|
||||
TextSpan(
|
||||
text: description,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: ColorsManager.blackColor,
|
||||
color: descriptionColor ?? ColorsManager.blackColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -64,18 +68,20 @@ class IncrementDecrementWidget extends StatelessWidget {
|
||||
),
|
||||
Material(
|
||||
type: MaterialType.transparency,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: InkWell(
|
||||
splashColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent,
|
||||
onTap: onIncrement,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 32,
|
||||
child: Flexible(
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
child: InkWell(
|
||||
splashColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent,
|
||||
onTap: onIncrement,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: ColorsManager.greyColor,
|
||||
size: 28,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -139,4 +139,9 @@ class Assets {
|
||||
"presence_sensor_assets/presence-sensor-assets/presence-sensor-motion.svg";
|
||||
|
||||
static const String lightPulp = "functions_icons/light_pulb.svg";
|
||||
|
||||
static const String acDevice = "functions_icons/ac_device.svg";
|
||||
|
||||
static const String acAirConditioner = "functions_icons/ac_air.svg";
|
||||
static const String acSun = "functions_icons/ac_sun.svg";
|
||||
}
|
||||
|
Reference in New Issue
Block a user