connect reports to main door

This commit is contained in:
ashrafzarkanisala
2024-09-18 02:23:42 +03:00
parent 9876ff2e03
commit 7c28012d79
7 changed files with 98 additions and 28 deletions

View File

@ -13,11 +13,15 @@ class DeviceReport {
DeviceReport.fromJson(Map<String, dynamic> json) DeviceReport.fromJson(Map<String, dynamic> json)
: deviceUuid = json['deviceUuid'] as String?, : deviceUuid = json['deviceUuid'] as String?,
startTime = json['startTime'] as int?, startTime = int.tryParse(json['startTime'].toString()) ??
endTime = json['endTime'] as int?, json['startTime'] as int?,
data = (json['data'] as List<dynamic>?) endTime =
int.tryParse(json['endTime'].toString()) ?? json['endTime'] as int?,
data = json['data'] != null
? (json['data'] as List<dynamic>?)
?.map((e) => DeviceEvent.fromJson(e as Map<String, dynamic>)) ?.map((e) => DeviceEvent.fromJson(e as Map<String, dynamic>))
.toList(); .toList()
: [];
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
'deviceUuid': deviceUuid, 'deviceUuid': deviceUuid,

View File

@ -1,4 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart'; import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_event.dart';
@ -63,16 +65,17 @@ class MainDoorSensorBloc
_timer = Timer(const Duration(milliseconds: 500), () async { _timer = Timer(const Duration(milliseconds: 500), () async {
try { try {
final status = await DevicesManagementApi() final response = await DevicesManagementApi()
.deviceControl(deviceId, Status(code: code, value: value)); .deviceControl(deviceId, Status(code: code, value: value));
if (!status) { if (!response) {
_revertValueAndEmit(deviceId, code, oldValue, emit); _revertValueAndEmit(deviceId, code, oldValue, emit);
} }
emit(MainDoorSensorDeviceStatusLoaded(deviceStatus));
} catch (e) { } catch (e) {
emit(MainDoorSensorFailedState(error: e.toString())); if (e is DioException && e.response != null) {
debugPrint('Error response: ${e.response?.data}');
}
_revertValueAndEmit(deviceId, code, oldValue, emit);
} }
}); });
} }
@ -93,7 +96,6 @@ class MainDoorSensorBloc
} }
} }
// Retrieve the current value by code
bool _getValueByCode(String code) { bool _getValueByCode(String code) {
switch (code) { switch (code) {
case 'doorcontact_state': case 'doorcontact_state':
@ -118,13 +120,12 @@ class MainDoorSensorBloc
} }
} }
// Fetch reports related to the main door sensor
FutureOr<void> _fetchReports(MainDoorSensorReportsEvent event, FutureOr<void> _fetchReports(MainDoorSensorReportsEvent event,
Emitter<MainDoorSensorState> emit) async { Emitter<MainDoorSensorState> emit) async {
emit(MainDoorSensorLoadingState()); emit(MainDoorSensorLoadingState());
try { try {
final reports = await DevicesManagementApi.getDeviceReports( final reports = await DevicesManagementApi.getDeviceReports(
event.deviceId, event.code); event.deviceId, event.code, event.from, event.to);
emit(MainDoorSensorReportLoaded(reports)); emit(MainDoorSensorReportLoaded(reports));
} catch (e) { } catch (e) {
emit(MainDoorSensorFailedState(error: e.toString())); emit(MainDoorSensorFailedState(error: e.toString()));

View File

@ -50,6 +50,14 @@ class MainDoorSensorBatchControl extends MainDoorSensorEvent {
class MainDoorSensorReportsEvent extends MainDoorSensorEvent { class MainDoorSensorReportsEvent extends MainDoorSensorEvent {
final String deviceId; final String deviceId;
final String code; final String code;
final String from;
final String to;
@override
List<Object> get props => [deviceId, code, from, to];
MainDoorSensorReportsEvent({required this.deviceId, required this.code}); MainDoorSensorReportsEvent(
{required this.deviceId,
required this.code,
required this.from,
required this.to});
} }

View File

@ -7,6 +7,7 @@ import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_do
import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_state.dart'; import 'package:syncrow_web/pages/device_managment/main_door_sensor/bloc/main_door_sensor_state.dart';
import 'package:syncrow_web/pages/device_managment/main_door_sensor/models/main_door_status_model.dart'; import 'package:syncrow_web/pages/device_managment/main_door_sensor/models/main_door_status_model.dart';
import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart'; import 'package:syncrow_web/pages/device_managment/shared/device_controls_container.dart';
import 'package:syncrow_web/pages/device_managment/shared/table/report_table.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart';
@ -25,10 +26,23 @@ class MainDoorSensorControlView extends StatelessWidget
..add(MainDoorSensorFetchDeviceEvent(device.uuid!)), ..add(MainDoorSensorFetchDeviceEvent(device.uuid!)),
child: BlocBuilder<MainDoorSensorBloc, MainDoorSensorState>( child: BlocBuilder<MainDoorSensorBloc, MainDoorSensorState>(
builder: (context, state) { builder: (context, state) {
if (state is MainDoorSensorLoadingState) { if (state is MainDoorSensorLoadingState ||
state is MainDoorSensorReportsLoadingState) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (state is MainDoorSensorDeviceStatusLoaded) { } else if (state is MainDoorSensorDeviceStatusLoaded) {
return _buildStatusControls(context, state.status); return _buildStatusControls(context, state.status);
} else if (state is MainDoorSensorReportLoaded) {
return ReportsTable(
report: state.deviceReport,
onRowTap: (index) {},
onClose: () {
context
.read<MainDoorSensorBloc>()
.add(MainDoorSensorFetchDeviceEvent(device.uuid!));
},
hideValueShowDescription: true,
mainDoorSensor: true,
);
} else if (state is MainDoorSensorFailedState || } else if (state is MainDoorSensorFailedState ||
state is MainDoorSensorBatchFailedState) { state is MainDoorSensorBatchFailedState) {
return const Center(child: Text('Error fetching status')); return const Center(child: Text('Error fetching status'));
@ -60,9 +74,15 @@ class MainDoorSensorControlView extends StatelessWidget
), ),
children: [ children: [
IconNameStatusContainer( IconNameStatusContainer(
name: 'Open', name: status.doorContactState ? 'Open' : 'Close',
icon: Assets.mainDoor, icon: Assets.mainDoor,
onTap: () {}, onTap: () {
context.read<MainDoorSensorBloc>().add(MainDoorSensorControl(
deviceId: device.uuid!,
code: 'doorcontact_state',
value: !status.doorContactState,
));
},
status: status.doorContactState, status: status.doorContactState,
textColor: ColorsManager.red, textColor: ColorsManager.red,
paddingAmount: 8, paddingAmount: 8,
@ -70,7 +90,20 @@ class MainDoorSensorControlView extends StatelessWidget
IconNameStatusContainer( IconNameStatusContainer(
name: 'Open/Close\n Record', name: 'Open/Close\n Record',
icon: Assets.mainDoorReports, icon: Assets.mainDoorReports,
onTap: () {}, onTap: () {
final from = DateTime.now()
.subtract(const Duration(days: 30))
.millisecondsSinceEpoch;
final to = DateTime.now().millisecondsSinceEpoch;
context.read<MainDoorSensorBloc>().add(
MainDoorSensorReportsEvent(
deviceId: device.uuid!,
code: 'doorcontact_state',
from: from.toString(),
to: to.toString(),
),
);
},
status: false, status: false,
textColor: ColorsManager.blackColor, textColor: ColorsManager.blackColor,
), ),

View File

@ -10,14 +10,18 @@ class ReportsTable extends StatelessWidget {
final String? thirdColumnDescription; final String? thirdColumnDescription;
final Function(int index) onRowTap; final Function(int index) onRowTap;
final VoidCallback onClose; final VoidCallback onClose;
bool? hideValueShowDescription;
bool? mainDoorSensor;
const ReportsTable({ ReportsTable({
super.key, super.key,
required this.report, required this.report,
required this.onRowTap, required this.onRowTap,
required this.onClose, required this.onClose,
this.thirdColumnTitle, this.thirdColumnTitle,
this.thirdColumnDescription, this.thirdColumnDescription,
this.hideValueShowDescription,
this.mainDoorSensor,
}); });
@override @override
@ -57,8 +61,18 @@ class ReportsTable extends StatelessWidget {
children: [ children: [
TableCellWidget(value: date), TableCellWidget(value: date),
TableCellWidget(value: time), TableCellWidget(value: time),
TableCellWidget( hideValueShowDescription == true
value: '${data.value!} ${thirdColumnDescription ?? ''}', ? TableCellWidget(
value: mainDoorSensor == true
? data.value == 'true'
? 'Open'
: 'Close'
: thirdColumnDescription ?? '',
onTap: () => onRowTap(index),
)
: TableCellWidget(
value:
'${data.value!} ${thirdColumnDescription ?? ''}',
onTap: () => onRowTap(index), onTap: () => onRowTap(index),
), ),
], ],

View File

@ -65,7 +65,8 @@ class DevicesManagementApi {
} }
} }
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async { static Future<List<DeviceModel>> getDevicesByGatewayId(
String gatewayId) async {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId), path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
showServerMessage: false, showServerMessage: false,
@ -94,9 +95,14 @@ class DevicesManagementApi {
return response; return response;
} }
static Future<DeviceReport> getDeviceReports(String uuid, String code) async { static Future<DeviceReport> getDeviceReports(String uuid, String code,
[String? from, String? to]) async {
final response = await HTTPService().get( final response = await HTTPService().get(
path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code), path: ApiEndpoints.getDeviceLogsByDate
.replaceAll('{uuid}', uuid)
.replaceAll('{code}', code)
.replaceAll('{startTime}', from ?? '')
.replaceAll('{endTime}', to ?? ''),
showServerMessage: false, showServerMessage: false,
expectedResponseModel: (json) { expectedResponseModel: (json) {
return DeviceReport.fromJson(json); return DeviceReport.fromJson(json);

View File

@ -11,12 +11,14 @@ abstract class ApiEndpoints {
static const String visitorPassword = '/visitor-password'; static const String visitorPassword = '/visitor-password';
static const String getDevices = '/visitor-password/devices'; static const String getDevices = '/visitor-password/devices';
static const String sendOnlineOneTime = '/visitor-password/temporary-password/online/one-time'; static const String sendOnlineOneTime =
'/visitor-password/temporary-password/online/one-time';
static const String sendOnlineMultipleTime = static const String sendOnlineMultipleTime =
'/visitor-password/temporary-password/online/multiple-time'; '/visitor-password/temporary-password/online/multiple-time';
//offline Password //offline Password
static const String sendOffLineOneTime = '/visitor-password/temporary-password/offline/one-time'; static const String sendOffLineOneTime =
'/visitor-password/temporary-password/offline/one-time';
static const String sendOffLineMultipleTime = static const String sendOffLineMultipleTime =
'/visitor-password/temporary-password/offline/multiple-time'; '/visitor-password/temporary-password/offline/multiple-time';
@ -32,4 +34,6 @@ abstract class ApiEndpoints {
static const String openDoorLock = '/door-lock/open/{doorLockUuid}'; static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}'; static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}';
static const String getDeviceLogsByDate =
'/device/report-logs/{uuid}?code={code}&startTime={startTime}&endTime={endTime}';
} }