diff --git a/.gitignore b/.gitignore index c3e0679..43d2746 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,11 @@ *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related diff --git a/ios/Podfile.lock b/ios/Podfile.lock index de7dea4..db4b41d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -329,4 +329,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 4243bd7f9184f79552dd731a7c9d5cad03bd2706 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 70693e4..b636303 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import UIKit import Flutter -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart index 1b979a6..6994bcc 100644 --- a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart +++ b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart @@ -18,6 +18,7 @@ class WallSensorBloc extends Bloc { on(_changeIndicator); on(_changeValue); on(_wallSensorUpdated); + on(_getDeviceReports); } void _fetchCeilingSensorStatus(InitialEvent event, Emitter emit) async { @@ -91,4 +92,17 @@ class WallSensorBloc extends Bloc { } catch (_) {} emit(UpdateState(wallSensorModel: deviceStatus)); } + + void _getDeviceReports(GetDeviceReportsEvent event, Emitter emit) async { + emit(LoadingInitialState()); + + try { + await DevicesAPI.getDeviceReports(deviceId, event.code).then((value) { + emit(DeviceReportsState(deviceReport: value, code: event.code)); + }); + } catch (e) { + emit(FailedState(error: e.toString())); + return; + } + } } diff --git a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart index 415c137..525f559 100644 --- a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart +++ b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart @@ -29,3 +29,15 @@ class ChangeValueEvent extends WallSensorEvent { @override List get props => [value, code]; } + +class GetDeviceReportsEvent extends WallSensorEvent { + final String deviceUuid; + final String code; + const GetDeviceReportsEvent({ + required this.deviceUuid, + required this.code, + }); + + @override + List get props => [deviceUuid, code]; +} diff --git a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart index 76ce10f..ce9bef2 100644 --- a/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart +++ b/lib/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart @@ -1,4 +1,5 @@ import 'package:equatable/equatable.dart'; +import 'package:syncrow_app/features/devices/model/device_report_model.dart'; import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart'; class WallSensorState extends Equatable { @@ -36,3 +37,9 @@ class FailedState extends WallSensorState { @override List get props => [error]; } + +class DeviceReportsState extends WallSensorState { + final DeviceReport deviceReport; + final String code; + const DeviceReportsState({required this.deviceReport, required this.code}); +} diff --git a/lib/features/devices/model/wall_sensor_model.dart b/lib/features/devices/model/wall_sensor_model.dart index 78dc9be..570d115 100644 --- a/lib/features/devices/model/wall_sensor_model.dart +++ b/lib/features/devices/model/wall_sensor_model.dart @@ -9,17 +9,18 @@ class WallSensorModel { int currentDistance; int illuminance; bool indicator; + int noOneTime; - WallSensorModel({ - required this.presenceState, - required this.farDetection, - required this.presenceTime, - required this.motionSensitivity, - required this.motionlessSensitivity, - required this.currentDistance, - required this.illuminance, - required this.indicator, - }); + WallSensorModel( + {required this.presenceState, + required this.farDetection, + required this.presenceTime, + required this.motionSensitivity, + required this.motionlessSensitivity, + required this.currentDistance, + required this.illuminance, + required this.indicator, + required this.noOneTime}); factory WallSensorModel.fromJson(List jsonList) { late String _presenceState; @@ -30,6 +31,7 @@ class WallSensorModel { late int _currentDistance; late int _illuminance; late bool _indicator; + late int _noOneTime; for (int i = 0; i < jsonList.length; i++) { if (jsonList[i].code == 'presence_state') { @@ -48,6 +50,8 @@ class WallSensorModel { _illuminance = jsonList[i].value ?? 0; } else if (jsonList[i].code == 'indicator') { _indicator = jsonList[i].value ?? false; + } else if (jsonList[i].code == 'no_one_time') { + _noOneTime = jsonList[i].value ?? 0; } } return WallSensorModel( @@ -58,6 +62,7 @@ class WallSensorModel { motionlessSensitivity: _motionlessSensitivity, currentDistance: _currentDistance, illuminance: _illuminance, - indicator: _indicator); + indicator: _indicator, + noOneTime: _noOneTime); } } diff --git a/lib/features/devices/view/widgets/wall_sensor/parameters_list.dart b/lib/features/devices/view/widgets/wall_sensor/parameters_list.dart index ccb3d01..56c7e87 100644 --- a/lib/features/devices/view/widgets/wall_sensor/parameters_list.dart +++ b/lib/features/devices/view/widgets/wall_sensor/parameters_list.dart @@ -215,8 +215,7 @@ class ParametersList extends StatelessWidget { { 'icon': Assets.assetsIconsPresenceSensorAssetsEmpty, 'title': 'Nobody Time', - 'code': null, - //TODO: Implement the nobody time + 'code': 'no_one_time', }, { 'icon': Assets.assetsIconsPresenceSensorAssetsIndicator, @@ -231,7 +230,7 @@ class ParametersList extends StatelessWidget { { 'icon': Assets.assetsIconsPresenceSensorAssetsIlluminanceRecord, 'title': 'Illuminance Record', - 'code': null + 'code': 'illuminance_value' }, ]; } @@ -240,6 +239,7 @@ Widget listItem(Map wallSensorButton, BuildContext context, Dev WallSensorModel wallSensorStatus) { String? unit; dynamic value; + int noBodyTimeValue; if (wallSensorButton['code'] != null) { // if (wallSensor.status.any((element) => element.code == wallSensorButton['code'] as String)) { // unit = unitsMap[wallSensorButton['code'] as String]; @@ -256,12 +256,15 @@ Widget listItem(Map wallSensorButton, BuildContext context, Dev } else if (wallSensorButton['code'] == 'illuminance_value') { unit = unitsMap[wallSensorButton['code'] as String]; value = wallSensorStatus.illuminance; + } else if (wallSensorButton['code'] == 'no_one_time') { + unit = unitsMap[wallSensorButton['code'] as String]; + value = wallSensorStatus.noOneTime; } } return DefaultContainer( margin: const EdgeInsets.only(bottom: 5), padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 20), - onTap: () { + onTap: () async { if (wallSensorButton['page'] != null) { Navigator.push( context, @@ -270,6 +273,42 @@ Widget listItem(Map wallSensorButton, BuildContext context, Dev ), ); } + if (wallSensorButton['title'] == 'Presence Record') { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => PresenceRecords( + deviceId: wallSensor.uuid!, + code: 'presence_state', + title: 'Presence Record', + )), + ); + } + + if (wallSensorButton['title'] == 'Illuminance Record') { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => PresenceRecords( + deviceId: wallSensor.uuid!, + code: 'illuminance_value', + title: 'Illuminance Record', + )), + ); + } + + if (wallSensorButton['title'] == 'Nobody Time') { + int noBodyTimeValue = value as int; + String controlCode = 'no_one_time'; + final result = await showDialog( + context: context, + builder: (context) => ParameterControlDialog( + title: 'Nobody Time', sensor: wallSensor, value: noBodyTimeValue, min: 0, max: 10000), + ); + + if (result != null) { + BlocProvider.of(context) + .add(ChangeValueEvent(value: result, code: controlCode)); + } + } }, child: Row( children: [ diff --git a/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart b/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart index 00b2373..e249b3d 100644 --- a/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart +++ b/lib/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart @@ -1,3 +1,5 @@ +import 'dart:ffi'; + import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -9,6 +11,8 @@ import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_e import 'package:syncrow_app/features/devices/model/device_model.dart'; import 'package:syncrow_app/features/devices/model/wall_sensor_model.dart'; import 'package:syncrow_app/features/devices/view/widgets/device_appbar.dart'; +import 'package:syncrow_app/features/devices/view/widgets/garage_door/garage_records_screen.dart'; +import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/persence_records.dart'; import 'package:syncrow_app/features/shared_widgets/default_container.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart'; import 'package:syncrow_app/features/shared_widgets/text_widgets/body_medium.dart'; @@ -41,7 +45,8 @@ class WallMountedInterface extends StatelessWidget { motionlessSensitivity: 0, currentDistance: 0, illuminance: 0, - indicator: false); + indicator: false, + noOneTime: 0); if (state is UpdateState) { wallSensorModel = state.wallSensorModel; diff --git a/lib/services/api/api_links_endpoints.dart b/lib/services/api/api_links_endpoints.dart index e556422..38e0686 100644 --- a/lib/services/api/api_links_endpoints.dart +++ b/lib/services/api/api_links_endpoints.dart @@ -209,4 +209,5 @@ abstract class ApiEndpoints { static const String resetDevice = '/factory/reset/{deviceUuid}'; static const String unAssignScenesDevice = '/device/{deviceUuid}/scenes?switchName={switchName}'; + static const String getDeviceLogs = '/device/report-logs/{uuid}?code={code}'; } diff --git a/lib/services/api/devices_api.dart b/lib/services/api/devices_api.dart index 646986d..7781b88 100644 --- a/lib/services/api/devices_api.dart +++ b/lib/services/api/devices_api.dart @@ -88,8 +88,7 @@ class DevicesAPI { static Future> getDeviceStatus(String deviceId) async { final response = await _httpService.get( - path: ApiEndpoints.deviceFunctionsStatus - .replaceAll('{deviceUuid}', deviceId), + path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { return json; @@ -98,8 +97,7 @@ class DevicesAPI { return response; } - static Future> getPowerClampStatus( - String deviceId) async { + static Future> getPowerClampStatus(String deviceId) async { final response = await _httpService.get( path: ApiEndpoints.powerClamp.replaceAll('{powerClampUuid}', deviceId), showServerMessage: false, @@ -111,9 +109,7 @@ class DevicesAPI { } static Future> renamePass( - {required String name, - required String doorLockUuid, - required String passwordId}) async { + {required String name, required String doorLockUuid, required String passwordId}) async { final response = await _httpService.put( path: ApiEndpoints.renamePassword .replaceAll('{doorLockUuid}', doorLockUuid) @@ -148,8 +144,7 @@ class DevicesAPI { return response; } - static Future getSceneBySwitchName( - {String? deviceId, String? switchName}) async { + static Future getSceneBySwitchName({String? deviceId, String? switchName}) async { final response = await _httpService.get( path: ApiEndpoints.fourSceneByName .replaceAll('{deviceUuid}', deviceId!) @@ -170,11 +165,7 @@ class DevicesAPI { final response = await _httpService.post( path: ApiEndpoints.deviceScene.replaceAll('{deviceUuid}', deviceId!), body: jsonEncode( - { - "switchName": switchName, - "sceneUuid": sceneUuid, - "spaceUuid": spaceUuid - }, + {"switchName": switchName, "sceneUuid": sceneUuid, "spaceUuid": spaceUuid}, ), showServerMessage: false, expectedResponseModel: (json) { @@ -194,8 +185,7 @@ class DevicesAPI { return response; } - static Future> getDeviceByGroupName( - String unitId, String groupName) async { + static Future> getDeviceByGroupName(String unitId, String groupName) async { final response = await _httpService.get( path: ApiEndpoints.devicesByGroupName .replaceAll('{unitUuid}', unitId) @@ -240,9 +230,7 @@ class DevicesAPI { if (json == null || json.isEmpty || json == []) { return []; } - return data - .map((device) => DeviceModel.fromJson(device)) - .toList(); + return data.map((device) => DeviceModel.fromJson(device)).toList(); }, ); @@ -254,8 +242,7 @@ class DevicesAPI { } } - static Future> getDevicesByGatewayId( - String gatewayId) async { + static Future> getDevicesByGatewayId(String gatewayId) async { final response = await _httpService.get( path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId), showServerMessage: false, @@ -277,8 +264,7 @@ class DevicesAPI { String deviceId, ) async { final response = await _httpService.get( - path: ApiEndpoints.getTemporaryPassword - .replaceAll('{doorLockUuid}', deviceId), + path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { return json; @@ -289,8 +275,7 @@ class DevicesAPI { static Future getOneTimePasswords(String deviceId) async { final response = await _httpService.get( - path: ApiEndpoints.getOneTimeTemporaryPassword - .replaceAll('{doorLockUuid}', deviceId), + path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { return json; @@ -301,8 +286,7 @@ class DevicesAPI { static Future getTimeLimitPasswords(String deviceId) async { final response = await _httpService.get( - path: ApiEndpoints.getMultipleTimeTemporaryPassword - .replaceAll('{doorLockUuid}', deviceId), + path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { return json; @@ -327,12 +311,10 @@ class DevicesAPI { "invalidTime": invalidTime, }; if (scheduleList != null) { - body["scheduleList"] = - scheduleList.map((schedule) => schedule.toJson()).toList(); + body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList(); } final response = await _httpService.post( - path: ApiEndpoints.addTemporaryPassword - .replaceAll('{doorLockUuid}', deviceId), + path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId), body: body, showServerMessage: false, expectedResponseModel: (json) => json, @@ -343,8 +325,7 @@ class DevicesAPI { static Future generateOneTimePassword({deviceId}) async { try { final response = await _httpService.post( - path: ApiEndpoints.addOneTimeTemporaryPassword - .replaceAll('{doorLockUuid}', deviceId), + path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId), showServerMessage: false, expectedResponseModel: (json) { return json; @@ -356,12 +337,10 @@ class DevicesAPI { } } - static Future generateMultiTimePassword( - {deviceId, effectiveTime, invalidTime}) async { + static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async { try { final response = await _httpService.post( - path: ApiEndpoints.addMultipleTimeTemporaryPassword - .replaceAll('{doorLockUuid}', deviceId), + path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId), showServerMessage: true, body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime}, expectedResponseModel: (json) { @@ -545,4 +524,18 @@ class DevicesAPI { ); return response; } + + static Future getDeviceReports( + String uuid, + String code, + ) async { + final response = await HTTPService().get( + path: ApiEndpoints.getDeviceLogs.replaceAll('{uuid}', uuid).replaceAll('{code}', code), + showServerMessage: false, + expectedResponseModel: (json) { + return DeviceReport.fromJson(json); + }, + ); + return response; + } } diff --git a/pubspec.yaml b/pubspec.yaml index bc5d09f..7fec07c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ description: This is the mobile application project, developed with Flutter for # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.0.9+45 +version: 1.0.10+46 environment: sdk: ">=3.0.6 <4.0.0"