Add status model and fetch device statuses

Added a new StatusModel class to represent device statuses and implemented
functionality to fetch and update device statuses in the DevicesCubit and
DeviceModel classes. Also updated UI components to display device status
information.
This commit is contained in:
Mohammad Salameh
2024-04-03 11:07:55 +03:00
parent 5ff5f65549
commit e49627d3e1
8 changed files with 134 additions and 32 deletions

View File

@ -8,6 +8,7 @@ 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_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart';
@ -280,6 +281,13 @@ class DevicesCubit extends Cubit<DevicesState> {
.indexWhere((element) => element.id == roomId);
HomeCubit.getInstance().selectedSpace!.rooms![roomIndex].devices =
await SpacesAPI.getDevicesByRoomId(roomId);
//get status for each device
for (var device in HomeCubit.getInstance()
.selectedSpace!
.rooms![roomIndex]
.devices!) {
getDevicesStatues(device.id!, roomIndex);
}
emitSafe(GetDevicesSuccess());
} on DioException catch (error) {
@ -289,6 +297,38 @@ class DevicesCubit extends Cubit<DevicesState> {
}
}
getDevicesStatues(String deviceId, int roomIndex) async {
if (_isClosed) return;
try {
emitSafe(GetDeviceStatusLoading());
int deviceIndex = HomeCubit.getInstance()
.selectedSpace!
.rooms![roomIndex]
.devices!
.indexWhere((element) => element.id == deviceId);
List<StatusModel> statuses = [];
var response = await DevicesAPI.getDeviceStatus(deviceId);
print('response : $response');
for (var status in response['result']['status']) {
statuses.add(StatusModel.fromJson(status));
}
HomeCubit.getInstance()
.selectedSpace!
.rooms![roomIndex]
.devices![deviceIndex]
.status = statuses;
emitSafe(GetDeviceStatusSuccess());
} on DioException catch (error) {
emitSafe(
GetDeviceStatusError(ServerFailure.fromDioError(error).errMessage),
);
}
}
///Lights
onHorizontalDragUpdate(DeviceModel light, double dx, double screenWidth) {
double newBrightness = (dx / (screenWidth - 15) * 100);

View File

@ -15,6 +15,16 @@ class ChangeIndex extends DevicesState {}
// Devices
class GetDeviceStatusLoading extends DevicesState {}
class GetDeviceStatusSuccess extends DevicesState {}
class GetDeviceStatusError extends DevicesState {
final String errorMsg;
GetDeviceStatusError(this.errorMsg);
}
class GetDevicesLoading extends DevicesState {}
class GetDevicesSuccess extends DevicesState {}

View File

@ -1,27 +1,29 @@
import 'package:syncrow_app/features/devices/model/function_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class DeviceModel {
int? activeTime;
String? category;
String? categoryName;
int? createTime;
String? gatewayId;
String? icon;
String? category; //unused
String? categoryName; //unused
int? createTime; //unused
String? gatewayId; //unused
String? icon; //unused
String? id;
String? ip;
double? lat;
String? ip; //unused
double? lat; //unused
String? localKey;
double? lon;
double? lon; //unused
String? model;
String? name;
String? nodeId; //rmeove
String? nodeId; //remove
bool? isOnline;
String? ownerId; //remove
String? productId; //remove
List<StatusModel> status = [];
String? ownerId; //unused
String? productId; //unused
String? productName;
bool? isSub;
bool? isSub; //unused
String? timeZone;
int? updateTime;
String? uuid;
@ -44,6 +46,7 @@ class DeviceModel {
this.name,
this.nodeId,
this.isOnline,
required this.status,
this.ownerId,
this.productId,
this.productName,
@ -102,6 +105,10 @@ class DeviceModel {
updateTime: json['updateTime'],
uuid: json['uuid'],
productType: type,
status: [],
// json['status']
// .map<StatusModel>((e) => StatusModel.fromJson(e))
// .toList(),
// devicesTypesMap[json['productName']] ?? DeviceType.Other,
);
}

View File

@ -0,0 +1,23 @@
class StatusModel {
String? code;
dynamic value;
StatusModel({
required this.code,
required this.value,
});
factory StatusModel.fromJson(Map<String, dynamic> json) {
return StatusModel(
code: json['code'],
value: json['value'],
);
}
Map<String, dynamic> toJson() {
return {
'code': code,
'value': value,
};
}
}

View File

@ -72,7 +72,11 @@ class AcInterfaceTempUnit extends StatelessWidget {
),
// min: DeviceModel.bounds.min,
// max: DeviceModel.bounds.max,
// initialValue: DeviceModel.temperature,
initialValue: deviceModel.status
.firstWhere(
(element) => element.code == 'temp_current')
.value /
10,
onChange: (value) {
String valueAsString = value.toStringAsFixed(1);
if (valueAsString.endsWith(".0") ||
@ -107,7 +111,8 @@ class AcInterfaceTempUnit extends StatelessWidget {
children: [
BodyLarge(
// text: "${DeviceModel.coolTo}° C",
text: '24° C',
text:
'${deviceModel.status.firstWhere((element) => element.code == 'temp_set').value / 10}° C',
style: context.bodyLarge.copyWith(
color:
ColorsManager.primaryColor.withOpacity(0.6),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
@ -17,18 +18,18 @@ class ACModeControlUnit extends StatefulWidget {
}
class _ACModeControlUnitState extends State<ACModeControlUnit> {
var fanSpeeds = [
Assets.iconsFan0,
Assets.iconsFan1,
Assets.iconsFan2,
Assets.iconsFan3,
];
Map<String, String> fanSpeedsMap = {
'auto': Assets.iconsFan0,
'iconsFan1': Assets.iconsFan1,
'iconsFan2': Assets.iconsFan2,
'iconsFan3': Assets.iconsFan3,
};
var tempModes = [
Assets.iconsSunnyMode,
Assets.iconsColdMode,
Assets.iconsWindyMode,
];
Map<String, String> tempModesMap = {
'sunny': Assets.iconsSunnyMode,
'cold': Assets.iconsColdMode,
'windy': Assets.iconsWindyMode,
};
@override
Widget build(BuildContext context) {
@ -43,10 +44,12 @@ class _ACModeControlUnitState extends State<ACModeControlUnit> {
// widget.model.fanSpeed == 3 ? 0 : widget.model.fanSpeed + 1;
});
},
child: const DefaultContainer(
child: DefaultContainer(
height: 55,
child: Center(
// child: SvgPicture.asset(fanSpeeds[widget.model.fanSpeed]),
child: SvgPicture.asset(fanSpeedsMap[widget.model.status
.firstWhere((element) => element.code == 'level')
.value]!),
),
),
),
@ -60,11 +63,12 @@ class _ACModeControlUnitState extends State<ACModeControlUnit> {
// widget.model.tempMode == 2 ? 0 : widget.model.tempMode + 1;
});
},
child: const DefaultContainer(
child: DefaultContainer(
height: 55,
child: Center(
// child: SvgPicture.asset(tempModes[widget.model.tempMode]),
child: SvgPicture.asset(tempModesMap[widget.model.status
.firstWhere((element) => element.code == 'mode')
.value]!),
),
),
),

View File

@ -17,6 +17,8 @@ abstract class ApiEndpoints {
// Devices
static const String control = '$baseUrl/device/control';
static const String devicesByRoom = '$baseUrl/device/room';
// static const String deviceStatus = '$baseUrl/device/status/';
static const String deviceStatus = '$baseUrl/device/';
//groups
static const String groups = '$baseUrl/group';

View File

@ -34,4 +34,15 @@ class DevicesAPI {
);
return response;
}
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
final response = await _httpService.get(
path: '${ApiEndpoints.deviceStatus}/$deviceId/functions/status',
showServerMessage: false,
expectedResponseModel: (json) {
return json;
},
);
return response;
}
}