mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-08-26 07:49:40 +00:00
door sensor
This commit is contained in:
23
assets/icons/door_sensor_icon.svg
Normal file
23
assets/icons/door_sensor_icon.svg
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<svg width="29" height="39" viewBox="0 0 29 39" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g filter="url(#filter0_i_3851_4689)">
|
||||||
|
<path d="M0 5.33646C0 2.84823 1.82766 0.716451 4.30322 0.46559C8.74889 0.0150898 12.2724 0.0349553 16.6673 0.476887C19.1549 0.727017 21 2.86372 21 5.36377V33.7227C21 36.1852 19.2096 38.3047 16.7627 38.5821C12.3371 39.0837 8.75437 39.0879 4.2429 38.579C1.794 38.3027 0 36.1827 0 33.7182V5.33646Z" fill="#EAF6FF"/>
|
||||||
|
</g>
|
||||||
|
<path d="M17.9558 24C18.0876 24 18.2194 23.9498 18.3199 23.8493C18.521 23.6481 18.521 23.3222 18.3199 23.1212C16.5988 21.4002 16.5988 18.5998 18.3199 16.8788C18.521 16.6777 18.521 16.3518 18.3199 16.1507C18.1188 15.9498 17.7929 15.9498 17.5918 16.1507C15.4693 18.2733 15.4693 21.7268 17.5918 23.8493C17.6923 23.9498 17.8241 24 17.9558 24Z" fill="#8AC9FE"/>
|
||||||
|
<path d="M19.0387 22C19.1493 22 19.2598 21.9578 19.3442 21.8735C19.5129 21.7048 19.5129 21.4313 19.3441 21.2626C19.0069 20.9254 18.8212 20.477 18.8212 20C18.8212 19.523 19.0069 19.0747 19.3441 18.7374C19.5129 18.5687 19.5129 18.2952 19.3442 18.1265C19.1754 17.9578 18.9019 17.9579 18.7333 18.1265C18.2329 18.6269 17.9573 19.2923 17.9573 20C17.9573 20.7078 18.2329 21.3731 18.7333 21.8735C18.8176 21.9578 18.9282 22 19.0387 22Z" fill="#8AC9FE"/>
|
||||||
|
<path d="M11.4131 31.3326L11.4131 33.2934C11.4131 33.6836 11.0969 34 10.7066 34C10.3163 34 10 33.6836 10 33.2934L10 31.3326C10 30.9423 10.3163 30.6261 10.7066 30.6261C11.0969 30.6261 11.4131 30.9423 11.4131 31.3326Z" fill="#B3DAFE"/>
|
||||||
|
<path d="M22 9.09138C22 8.20685 22.5774 7.4095 23.4429 7.22709C24.914 6.91707 26.0828 6.92986 27.5356 7.23253C28.4104 7.41477 29 8.21687 29 9.11042V31.8825C29 32.7476 28.4479 33.5327 27.6064 33.733C26.117 34.0877 24.9156 34.0909 23.3975 33.7314C22.5543 33.5317 22 32.746 22 31.8795V9.09138Z" fill="#EAF6FF"/>
|
||||||
|
<path d="M24.5149 24C24.3831 24 24.2514 23.9498 24.1508 23.8493C23.9497 23.6481 23.9497 23.3222 24.1508 23.1212C25.8719 21.4002 25.8719 18.5998 24.1508 16.8788C23.9497 16.6777 23.9497 16.3518 24.1508 16.1507C24.3519 15.9498 24.6778 15.9498 24.8789 16.1507C27.0014 18.2733 27.0014 21.7268 24.8789 23.8493C24.7784 23.9498 24.6466 24 24.5149 24Z" fill="#8AC9FE"/>
|
||||||
|
<path d="M23.432 22C23.3214 22 23.2109 21.9578 23.1265 21.8735C22.9578 21.7048 22.9578 21.4313 23.1266 21.2626C23.4638 20.9254 23.6495 20.477 23.6495 20C23.6495 19.523 23.4638 19.0747 23.1266 18.7374C22.9578 18.5687 22.9578 18.2952 23.1265 18.1265C23.2953 17.9578 23.5688 17.9579 23.7374 18.1265C24.2378 18.6269 24.5134 19.2923 24.5134 20C24.5134 20.7078 24.2379 21.3731 23.7374 21.8735C23.6531 21.9578 23.5425 22 23.432 22Z" fill="#8AC9FE"/>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_i_3851_4689" x="-1" y="0.136475" width="22" height="38.823" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-1"/>
|
||||||
|
<feGaussianBlur stdDeviation="1.5"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.538295 0 0 0 0 0.538295 0 0 0 0 0.538295 0 0 0 0.3 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_3851_4689"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
@ -6,19 +6,18 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
|
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
|
||||||
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
|
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/door_sensor_model.dart';
|
import 'package:syncrow_app/features/devices/model/door_sensor_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/report_model.dart';
|
|
||||||
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
import 'package:syncrow_app/features/devices/model/status_model.dart';
|
||||||
import 'package:syncrow_app/services/api/devices_api.dart';
|
import 'package:syncrow_app/services/api/devices_api.dart';
|
||||||
|
|
||||||
class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
||||||
final String DSId;
|
final String DSId;
|
||||||
final String switchCode;
|
DoorSensorBloc({
|
||||||
DoorSensorBloc({required this.DSId, required this.switchCode})
|
required this.DSId,
|
||||||
: super(const DoorSensorState()) {
|
}) : super(const DoorSensorState()) {
|
||||||
on<DoorSensorInitial>(_fetchWaterHeaterStatus);
|
on<DoorSensorInitial>(_fetchWaterHeaterStatus);
|
||||||
on<ReportLogsInitial>(fetchLogsForLastMonth);
|
on<ReportLogsInitial>(fetchLogsForLastMonth);
|
||||||
on<DoorSensorSwitch>(_changeFirstSwitch);
|
|
||||||
on<ToggleLowBatteryEvent>(_toggleLowBattery);
|
on<ToggleLowBatteryEvent>(_toggleLowBattery);
|
||||||
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
|
||||||
on<ToggleDoorAlarmEvent>(_toggleDoorAlarm);
|
on<ToggleDoorAlarmEvent>(_toggleDoorAlarm);
|
||||||
@ -29,6 +28,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
bool doorAlarm = false;
|
bool doorAlarm = false;
|
||||||
DoorSensorModel deviceStatus =
|
DoorSensorModel deviceStatus =
|
||||||
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
|
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
|
||||||
|
|
||||||
void _fetchWaterHeaterStatus(
|
void _fetchWaterHeaterStatus(
|
||||||
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
|
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
|
||||||
emit(DoorSensorLoadingState());
|
emit(DoorSensorLoadingState());
|
||||||
@ -43,34 +43,13 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
);
|
);
|
||||||
emit(UpdateState(doorSensor: deviceStatus));
|
emit(UpdateState(doorSensor: deviceStatus));
|
||||||
Future.delayed(const Duration(milliseconds: 500));
|
Future.delayed(const Duration(milliseconds: 500));
|
||||||
// _listenToChanges();
|
_listenToChanges();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(DoorSensorFailedState(errorMessage: e.toString()));
|
emit(DoorSensorFailedState(errorMessage: e.toString()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _changeFirstSwitch(
|
|
||||||
DoorSensorSwitch event, Emitter<DoorSensorState> emit) async {
|
|
||||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
|
||||||
try {
|
|
||||||
deviceStatus.doorContactState = !event.switchD;
|
|
||||||
emit(UpdateState(doorSensor: deviceStatus));
|
|
||||||
final response = await DevicesAPI.controlDevice(
|
|
||||||
DeviceControlModel(
|
|
||||||
deviceId: DSId,
|
|
||||||
code: 'doorcontact_state',
|
|
||||||
value: deviceStatus.doorContactState),
|
|
||||||
DSId);
|
|
||||||
|
|
||||||
if (!response['success']) {
|
|
||||||
// add(InitialEvent(groupScreen: oneGangGroup));
|
|
||||||
}
|
|
||||||
} catch (_) {
|
|
||||||
emit(DoorSensorFailedState(errorMessage: _.toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle functions for each switch
|
// Toggle functions for each switch
|
||||||
void _toggleLowBattery(
|
void _toggleLowBattery(
|
||||||
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
|
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
|
||||||
@ -135,31 +114,8 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<RecordGroup> recordGroups = [
|
DeviceReport recordGroups = DeviceReport(startTime: 0, endTime: 0, data: []);
|
||||||
RecordGroup(
|
|
||||||
date: DateTime(2024, 8, 31),
|
|
||||||
records: [
|
|
||||||
Record(status: 'Opened', time: '15:10:25', isOpen: false),
|
|
||||||
Record(status: 'Closed', time: '12:24:45', isOpen: false),
|
|
||||||
Record(status: 'Opened', time: '12:20:05', isOpen: true),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
RecordGroup(
|
|
||||||
date: DateTime(2024, 8, 30),
|
|
||||||
records: [
|
|
||||||
Record(status: 'Opened', time: '14:15:30', isOpen: true),
|
|
||||||
Record(status: 'Closed', time: '10:22:45', isOpen: false),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
RecordGroup(
|
|
||||||
date: DateTime(2024, 8, 29),
|
|
||||||
records: [
|
|
||||||
Record(status: 'Opened', time: '13:45:00', isOpen: true),
|
|
||||||
Record(status: 'Closed', time: '11:30:15', isOpen: false),
|
|
||||||
Record(status: 'Opened', time: '09:20:10', isOpen: true),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
Future<void> fetchLogsForLastMonth(
|
Future<void> fetchLogsForLastMonth(
|
||||||
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
|
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
|
||||||
@ -174,11 +130,13 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
int endTime = now.millisecondsSinceEpoch;
|
int endTime = now.millisecondsSinceEpoch;
|
||||||
try {
|
try {
|
||||||
var response = await DevicesAPI.getReportLogs(
|
var response = await DevicesAPI.getReportLogs(
|
||||||
startTime: startTime.toString(), // Convert to String if the API expects it
|
startTime:
|
||||||
|
startTime.toString(), // Convert to String if the API expects it
|
||||||
endTime: endTime.toString(), // Convert to String if the API expects it
|
endTime: endTime.toString(), // Convert to String if the API expects it
|
||||||
deviceUuid: DSId,
|
deviceUuid: DSId,
|
||||||
code: 'doorcontact_state',
|
code: 'doorcontact_state',
|
||||||
);
|
);
|
||||||
|
recordGroups = response;
|
||||||
// Process response here
|
// Process response here
|
||||||
print(response);
|
print(response);
|
||||||
} on DioException catch (e) {
|
} on DioException catch (e) {
|
||||||
@ -204,8 +162,7 @@ class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
|
|||||||
List<StatusModel> statusList = [];
|
List<StatusModel> statusList = [];
|
||||||
|
|
||||||
usersMap['status'].forEach((element) {
|
usersMap['status'].forEach((element) {
|
||||||
statusList
|
statusList.add(StatusModel(code: element['code'], value: true));
|
||||||
.add(StatusModel(code: element['code'], value: element['value']));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
deviceStatus = DoorSensorModel.fromJson(statusList);
|
deviceStatus = DoorSensorModel.fromJson(statusList);
|
||||||
|
@ -42,7 +42,9 @@ class DevicesCategoryModel {
|
|||||||
: name = json['groupName'],
|
: name = json['groupName'],
|
||||||
// id = json['groupId'],
|
// id = json['groupId'],
|
||||||
type = devicesTypesMap[json['groupName']] ?? DeviceType.Other,
|
type = devicesTypesMap[json['groupName']] ?? DeviceType.Other,
|
||||||
icon = deviceTypeIconMap[devicesTypesMap[json['groupName']] ?? DeviceType.Other] ?? '',
|
icon = deviceTypeIconMap[
|
||||||
|
devicesTypesMap[json['groupName']] ?? DeviceType.Other] ??
|
||||||
|
'',
|
||||||
devices = [],
|
devices = [],
|
||||||
isSelected = false;
|
isSelected = false;
|
||||||
|
|
||||||
@ -60,5 +62,9 @@ Map<DeviceType, String> deviceTypeIconMap = {
|
|||||||
DeviceType.CeilingSensor: Assets.assetsIconsSensors,
|
DeviceType.CeilingSensor: Assets.assetsIconsSensors,
|
||||||
DeviceType.WallSensor: Assets.assetsIconsSensors,
|
DeviceType.WallSensor: Assets.assetsIconsSensors,
|
||||||
DeviceType.ThreeGang: Assets.assetsIconsGang,
|
DeviceType.ThreeGang: Assets.assetsIconsGang,
|
||||||
|
DeviceType.OneGang: Assets.oneGang,
|
||||||
|
DeviceType.TwoGang: Assets.twoGang,
|
||||||
|
DeviceType.WH: Assets.waterHeaterIcon,
|
||||||
|
DeviceType.DS: Assets.doorSensorIcon,
|
||||||
DeviceType.Other: Assets.assetsIconsAC,
|
DeviceType.Other: Assets.assetsIconsAC,
|
||||||
};
|
};
|
||||||
|
@ -62,11 +62,14 @@ class DeviceModel {
|
|||||||
tempIcon = Assets.oneGang;
|
tempIcon = Assets.oneGang;
|
||||||
} else if (type == DeviceType.TwoGang) {
|
} else if (type == DeviceType.TwoGang) {
|
||||||
tempIcon = Assets.twoGang;
|
tempIcon = Assets.twoGang;
|
||||||
}else if (type == DeviceType.WH) {
|
} else if (type == DeviceType.WH) {
|
||||||
tempIcon = Assets.waterHeaterIcon;
|
tempIcon = Assets.waterHeaterIcon;
|
||||||
|
} else if (type == DeviceType.DS) {
|
||||||
|
tempIcon = Assets.doorSensorIcon;
|
||||||
} else {
|
} else {
|
||||||
tempIcon = Assets.assetsIconsLogo;
|
tempIcon = Assets.assetsIconsLogo;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DeviceModel(
|
return DeviceModel(
|
||||||
icon: tempIcon,
|
icon: tempIcon,
|
||||||
activeTime: json['activeTime'],
|
activeTime: json['activeTime'],
|
||||||
|
51
lib/features/devices/model/device_report_model.dart
Normal file
51
lib/features/devices/model/device_report_model.dart
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
class DeviceReport {
|
||||||
|
final String? deviceUuid;
|
||||||
|
final int? startTime;
|
||||||
|
final int? endTime;
|
||||||
|
final List<DeviceEvent>? data;
|
||||||
|
|
||||||
|
DeviceReport({
|
||||||
|
this.deviceUuid,
|
||||||
|
this.startTime,
|
||||||
|
this.endTime,
|
||||||
|
this.data,
|
||||||
|
});
|
||||||
|
|
||||||
|
DeviceReport.fromJson(Map<String, dynamic> json)
|
||||||
|
: deviceUuid = json['deviceUuid'] as String?,
|
||||||
|
startTime = json['startTime'] as int?,
|
||||||
|
endTime = json['endTime'] as int?,
|
||||||
|
data = (json['data'] as List<dynamic>?)
|
||||||
|
?.map((e) => DeviceEvent.fromJson(e as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'deviceUuid': deviceUuid,
|
||||||
|
'startTime': startTime,
|
||||||
|
'endTime': endTime,
|
||||||
|
'data': data?.map((e) => e.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class DeviceEvent {
|
||||||
|
final String? code;
|
||||||
|
final int? eventTime;
|
||||||
|
final String? value;
|
||||||
|
|
||||||
|
DeviceEvent({
|
||||||
|
this.code,
|
||||||
|
this.eventTime,
|
||||||
|
this.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
DeviceEvent.fromJson(Map<String, dynamic> json)
|
||||||
|
: code = json['code'] as String?,
|
||||||
|
eventTime = json['eventTime'] as int?,
|
||||||
|
value = json['value'] as String?;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'code': code,
|
||||||
|
'eventTime': eventTime,
|
||||||
|
'value': value,
|
||||||
|
};
|
||||||
|
}
|
@ -16,8 +16,8 @@ class NotificationSettingsPage extends StatelessWidget {
|
|||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
title: 'Notification Settings',
|
title: 'Notification Settings',
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => DoorSensorBloc(switchCode: 'switch_1', DSId: '')
|
create: (context) =>
|
||||||
..add(const DoorSensorInitial()),
|
DoorSensorBloc(DSId: '')..add(const DoorSensorInitial()),
|
||||||
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
||||||
|
@ -7,71 +7,115 @@ import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_s
|
|||||||
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
|
||||||
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
|
||||||
|
|
||||||
|
// // class DoorRecordsScreen extends StatelessWidget {
|
||||||
|
// final String DSId;
|
||||||
|
// const DoorRecordsScreen({super.key, required this.DSId});
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return DefaultScaffold(
|
||||||
|
// title: 'Records',
|
||||||
|
// child: BlocProvider(
|
||||||
|
// create: (context) =>
|
||||||
|
// DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
|
||||||
|
// child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
||||||
|
// builder: (context, state) {
|
||||||
|
// final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
||||||
|
// return SizedBox(
|
||||||
|
// child: ListView.builder(
|
||||||
|
// itemCount: doorSensorBloc.recordGroups!.data!.length,
|
||||||
|
// itemBuilder: (context, index) {
|
||||||
|
// final recordGroup = doorSensorBloc.recordGroups!.data![index];
|
||||||
|
|
||||||
class DoorRecordsScreen extends StatelessWidget {
|
class DoorRecordsScreen extends StatelessWidget {
|
||||||
final String DSId;
|
final String DSId;
|
||||||
const DoorRecordsScreen({super.key,required this.DSId});
|
const DoorRecordsScreen({super.key, required this.DSId});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return DefaultScaffold(
|
return DefaultScaffold(
|
||||||
title: 'Records',
|
title: 'Records',
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) =>
|
create: (context) =>
|
||||||
DoorSensorBloc(switchCode: 'switch_1', DSId:DSId )
|
DoorSensorBloc(DSId: DSId)..add(const ReportLogsInitial()),
|
||||||
..add(const ReportLogsInitial()),
|
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
||||||
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
builder: (context, state) {
|
||||||
builder: (context, state) {
|
if (state is DoorSensorLoadingState) {
|
||||||
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
|
return const Center(child: CircularProgressIndicator());
|
||||||
return SizedBox(
|
}
|
||||||
child: ListView.builder(
|
|
||||||
itemCount: doorSensorBloc.recordGroups.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final recordGroup = doorSensorBloc.recordGroups[index];
|
|
||||||
|
|
||||||
return Column(
|
if (state is DoorSensorFailedState) {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
return Center(
|
||||||
children: [
|
child: Text('Failed to load data: ${state.errorMessage}'),
|
||||||
// Date header
|
);
|
||||||
Padding(
|
}
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Text(
|
if (state is UpdateState && state.doorSensor != null) {
|
||||||
DateFormat('EEEE, dd/MM/yyyy')
|
final recordGroups = context.read<DoorSensorBloc>().recordGroups;
|
||||||
.format(recordGroup.date),
|
|
||||||
|
if (recordGroups == null ||
|
||||||
|
recordGroups.data == null ||
|
||||||
|
recordGroups.data!.isEmpty) {
|
||||||
|
return const Center(child: Text('No records available.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: recordGroups.data!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final record = recordGroups.data![index];
|
||||||
|
|
||||||
|
// Convert eventTime to a human-readable format
|
||||||
|
final DateTime eventDateTime =
|
||||||
|
DateTime.fromMillisecondsSinceEpoch(record.eventTime!);
|
||||||
|
final String formattedDate =
|
||||||
|
DateFormat('EEEE, dd/MM/yyyy').format(eventDateTime);
|
||||||
|
final String formattedTime =
|
||||||
|
DateFormat('HH:mm:ss').format(eventDateTime);
|
||||||
|
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
// Date header
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Text(
|
||||||
|
formattedDate,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Display the event details in DefaultContainer
|
||||||
|
DefaultContainer(
|
||||||
|
child: ListTile(
|
||||||
|
leading: Icon(
|
||||||
|
record.value == 'true'
|
||||||
|
? Icons.radio_button_checked
|
||||||
|
: Icons.radio_button_unchecked,
|
||||||
|
color: record.value == 'true'
|
||||||
|
? Colors.blue
|
||||||
|
: Colors.grey,
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
'Status: ${record.value}',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 18,
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 18,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
subtitle: Text('Time: $formattedTime'),
|
||||||
),
|
),
|
||||||
// Display each record for the date
|
),
|
||||||
DefaultContainer(
|
],
|
||||||
child: Column(
|
);
|
||||||
children: recordGroup.records.map((record) {
|
},
|
||||||
return ListTile(
|
|
||||||
leading: Icon(
|
|
||||||
record.isOpen
|
|
||||||
? Icons.radio_button_checked
|
|
||||||
: Icons.radio_button_unchecked,
|
|
||||||
color:
|
|
||||||
record.isOpen ? Colors.blue : Colors.grey,
|
|
||||||
),
|
|
||||||
title: Text(
|
|
||||||
record.status,
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: Text(record.time),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
})));
|
}
|
||||||
|
|
||||||
|
return const Center(child: Text('No data available.'));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ class DoorSensorScreen extends StatelessWidget {
|
|||||||
title: 'Door Sensor',
|
title: 'Door Sensor',
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) =>
|
create: (context) =>
|
||||||
DoorSensorBloc(switchCode: 'switch_1', DSId: device?.uuid ?? '')
|
DoorSensorBloc( DSId: device?.uuid ?? '')
|
||||||
..add(const DoorSensorInitial()),
|
..add(const DoorSensorInitial()),
|
||||||
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
|
@ -1058,4 +1058,5 @@ class Assets {
|
|||||||
static const String doorNotificationSetting =
|
static const String doorNotificationSetting =
|
||||||
"assets/icons/door_notification_setting_icon.svg";
|
"assets/icons/door_notification_setting_icon.svg";
|
||||||
static const String doorRecordsIcon = "assets/icons/door_records_icon.svg";
|
static const String doorRecordsIcon = "assets/icons/door_records_icon.svg";
|
||||||
|
static const String doorSensorIcon = "assets/icons/door_sensor_icon.svg";
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
|||||||
import 'package:syncrow_app/features/devices/model/device_category_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_control_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
import 'package:syncrow_app/features/devices/model/device_model.dart';
|
||||||
|
import 'package:syncrow_app/features/devices/model/device_report_model.dart';
|
||||||
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
import 'package:syncrow_app/features/devices/model/function_model.dart';
|
||||||
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
import 'package:syncrow_app/services/api/api_links_endpoints.dart';
|
||||||
import 'package:syncrow_app/services/api/http_service.dart';
|
import 'package:syncrow_app/services/api/http_service.dart';
|
||||||
@ -358,7 +359,7 @@ class DevicesAPI {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future getReportLogs({
|
static Future<DeviceReport> getReportLogs({
|
||||||
required String deviceUuid,
|
required String deviceUuid,
|
||||||
required String code,
|
required String code,
|
||||||
required String startTime,
|
required String startTime,
|
||||||
@ -373,7 +374,7 @@ class DevicesAPI {
|
|||||||
.replaceAll('{startTime}', startTime)
|
.replaceAll('{startTime}', startTime)
|
||||||
.replaceAll('{endTime}', endTime),
|
.replaceAll('{endTime}', endTime),
|
||||||
expectedResponseModel: (json) {
|
expectedResponseModel: (json) {
|
||||||
print('====---------${json}');
|
return DeviceReport.fromJson(json);
|
||||||
return json;
|
return json;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user