Files
syncrow-app/lib/features/devices/model/device_model.dart

229 lines
6.6 KiB
Dart

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? id;
String? localKey;
String? model;
String? name;
String? icon;
String? categoryName;
bool? toggleStatus = false;
String? type;
bool? isOnline;
List<StatusModel> status = [];
String? productName;
String? timeZone;
int? updateTime;
String? uuid;
String? productUuid;
DeviceType? productType;
bool isSelected = false;
late List<FunctionModel> functions;
DeviceSubspace? subspace;
DeviceModel(
{this.activeTime,
this.productUuid,
this.localKey,
this.model,
this.name,
this.isOnline,
required this.status,
this.productName,
this.timeZone,
this.updateTime,
this.uuid,
this.productType,
this.categoryName,
this.subspace,
this.toggleStatus,
this.icon,
this.type}) {
functions = getFunctions(productType!);
}
factory DeviceModel.fromJson(Map<String, dynamic> json) {
String tempIcon = '';
DeviceType type = devicesTypesMap[json['productType']] ?? DeviceType.Other;
if (type == DeviceType.LightBulb) {
tempIcon = Assets.assetsIconsLight;
} else if (type == DeviceType.CeilingSensor ||
type == DeviceType.WallSensor) {
tempIcon = Assets.assetsIconsSensors;
} else if (type == DeviceType.AC) {
tempIcon = Assets.assetsIconsAC;
} else if (type == DeviceType.DoorLock) {
tempIcon = Assets.assetsIconsDoorLock;
} else if (type == DeviceType.Curtain) {
tempIcon = Assets.assetsIconsCurtain;
} else if (type == DeviceType.ThreeGang) {
tempIcon = Assets.assetsIcons3GangSwitch;
} else if (type == DeviceType.Gateway) {
tempIcon = Assets.assetsIconsGateway;
} else if (type == DeviceType.OneGang) {
tempIcon = Assets.oneGang;
} else if (type == DeviceType.TwoGang) {
tempIcon = Assets.twoGang;
} else if (type == DeviceType.WH) {
tempIcon = Assets.waterHeaterIcon;
} else if (type == DeviceType.DS) {
tempIcon = Assets.doorSensorIcon;
} else if (type == DeviceType.OneTouch) {
tempIcon = Assets.gang1touch;
} else if (type == DeviceType.TowTouch) {
tempIcon = Assets.gang2touch;
} else if (type == DeviceType.GarageDoor) {
tempIcon = Assets.garageIcon;
} else if (type == DeviceType.ThreeTouch) {
tempIcon = Assets.gang3touch;
} else if (type == DeviceType.WaterLeak) {
tempIcon = Assets.waterLeakIcon;
} else if (type == DeviceType.PC) {
tempIcon = Assets.powerClampIcon;
} else if (type == DeviceType.FourScene) {
tempIcon = Assets.fourSceneHomeIcon;
} else if (type == DeviceType.SixScene) {
tempIcon = Assets.sixSceneHomeIcon;
} else if (type == DeviceType.SOS) {
tempIcon = Assets.sosHomeIcon;
} else if (type == DeviceType.FlushMountedSensor) {
tempIcon = Assets.flushIcon;
} else {
tempIcon = Assets.assetsIconsLogo;
}
// Step 1: Parse `status` as before
final statusList = (json['status'] as List<dynamic>?)
?.map((st) => StatusModel.fromJson(st as Map<String, dynamic>))
.toList();
// Step 2: Check whether ANY status means "off"
final anyOff = statusList?.any((s) {
final code = s.code;
if (code == null) return false;
// 1) Handle "switch" or "switch_x"
if (code == 'switch' || code.startsWith('switch_')) {
// If it's false, we consider that "off"
return s.value == false;
}
// 2) If code == "control" and value == "stop", consider "off"
if (s.value == 'open') {
return true;
}
// 3) If code == "percent_control" and value == 0, maybe "off"
if (code == 'percent_control' && s.value == 0) {
return true;
}
// Add more conditions for other codes as needed
// Default: if none of the above apply, it's not "off"
return false;
});
// Step 3: Decide final toggleStatus (true = fully "on", false = partially/fully "off")
bool computedToggleStatus = !(anyOff ?? false);
return DeviceModel(
icon: tempIcon,
activeTime: json['activeTime'],
categoryName: json['categoryName'],
localKey: json['localKey'],
model: json['model'],
name: json['name'],
isOnline: json['online'],
productName: json['productName'],
timeZone: json['timeZone'],
updateTime: json['updateTime'],
uuid: json['uuid'],
productType: type,
type: json['productType'],
// Use the newly computed toggleStatus:
toggleStatus: computedToggleStatus,
// Or if you prefer to use the value returned by the backend when available:
// toggleStatus: json['toggleStatus'] ?? computedToggleStatus,
status: statusList ?? [],
subspace: json['subspace'] != null
? DeviceSubspace.fromJson(json['subspace'])
: DeviceSubspace(
createdAt: null,
disabled: false,
subspaceName: '',
updatedAt: null,
uuid: '',
),
productUuid: json['productUuid'],
);
}
Map<String, dynamic> toJson() {
return {
'activeTime': activeTime,
'localKey': localKey,
'model': model,
'name': name,
'online': isOnline,
'productName': productName,
'timeZone': timeZone,
'updateTime': updateTime,
'uuid': uuid,
'productType': productType,
'subspace': subspace?.toJson(), // serialize subspace
};
}
List<FunctionModel> getFunctions(DeviceType type) =>
devicesFunctionsMap[productType] ?? [];
}
class DeviceSubspace {
String? uuid;
DateTime? createdAt;
DateTime? updatedAt;
String? subspaceName;
bool? disabled;
DeviceSubspace({
this.uuid,
this.createdAt,
this.updatedAt,
this.subspaceName,
this.disabled,
});
factory DeviceSubspace.fromJson(Map<String, dynamic> json) {
return DeviceSubspace(
uuid: json['uuid'],
createdAt: json['createdAt'] != null
? DateTime.tryParse(json['createdAt'])
: null,
updatedAt: json['updatedAt'] != null
? DateTime.tryParse(json['updatedAt'])
: null,
subspaceName: json['subspaceName'],
disabled: json['disabled'],
);
}
Map<String, dynamic> toJson() {
return {
'uuid': uuid,
'createdAt': createdAt?.toIso8601String(),
'updatedAt': updatedAt?.toIso8601String(),
'subspaceName': subspaceName,
'disabled': disabled,
};
}
}