implemented ceiling and wall sensors, and bug fixes

This commit is contained in:
Abdullah Alassaf
2024-08-26 15:35:18 +03:00
parent 929b72d11a
commit afee0eb5b1
98 changed files with 920 additions and 671 deletions

View File

@ -0,0 +1,87 @@
import 'dart:async';
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/ceiling_sensor/bloc/event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/state.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
import 'package:syncrow_web/services/devices_mang_api.dart';
class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
final String deviceId;
late CeilingSensorModel deviceStatus;
Timer? _timer;
CeilingSensorBloc({required this.deviceId}) : super(CeilingInitialState()) {
on<CeilingInitialEvent>(_fetchCeilingSensorStatus);
on<CeilingChangeValueEvent>(_changeValue);
}
void _fetchCeilingSensorStatus(
CeilingInitialEvent event, Emitter<CeilingSensorState> emit) async {
emit(CeilingLoadingInitialState());
try {
var response = await DevicesManagementApi().getDeviceStatus(deviceId);
deviceStatus = CeilingSensorModel.fromJson(response.status);
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
// _listenToChanges();
} catch (e) {
emit(CeilingFailedState(error: e.toString()));
return;
}
}
// _listenToChanges() {
// try {
// DatabaseReference ref = FirebaseDatabase.instance.ref('device-status/$deviceId');
// Stream<DatabaseEvent> stream = ref.onValue;
// stream.listen((DatabaseEvent event) {
// Map<dynamic, dynamic> usersMap = event.snapshot.value as Map<dynamic, dynamic>;
// List<StatusModel> statusList = [];
// usersMap['status'].forEach((element) {
// statusList.add(StatusModel(code: element['code'], value: element['value']));
// });
// deviceStatus = WallSensorModel.fromJson(statusList);
// add(WallSensorUpdatedEvent());
// });
// } catch (_) {}
// }
void _changeValue(CeilingChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
emit(CeilingLoadingNewSate(ceilingSensorModel: deviceStatus));
if (event.code == 'sensitivity') {
deviceStatus.sensitivity = event.value;
} else if (event.code == 'none_body_time') {
deviceStatus.noBodyTime = event.value;
} else if (event.code == 'moving_max_dis') {
deviceStatus.maxDistance = event.value;
}
emit(CeilingUpdateState(ceilingSensorModel: deviceStatus));
await _runDeBouncer(deviceId: deviceId, code: event.code, value: event.value);
}
_runDeBouncer({
required String deviceId,
required String code,
required dynamic value,
}) {
if (_timer != null) {
_timer!.cancel();
}
_timer = Timer(const Duration(seconds: 1), () async {
try {
final response =
await DevicesManagementApi().deviceControl(deviceId, Status(code: code, value: value));
if (!response) {
add(CeilingInitialEvent());
}
} catch (_) {
await Future.delayed(const Duration(milliseconds: 500));
add(CeilingInitialEvent());
}
});
}
}

View File

@ -0,0 +1,19 @@
import 'package:equatable/equatable.dart';
abstract class CeilingSensorEvent extends Equatable {
const CeilingSensorEvent();
@override
List<Object> get props => [];
}
class CeilingInitialEvent extends CeilingSensorEvent {}
class CeilingChangeValueEvent extends CeilingSensorEvent {
final int value;
final String code;
const CeilingChangeValueEvent({required this.value, required this.code});
@override
List<Object> get props => [value, code];
}

View File

@ -0,0 +1,38 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/model/ceiling_sensor_model.dart';
class CeilingSensorState extends Equatable {
const CeilingSensorState();
@override
List<Object> get props => [];
}
class CeilingInitialState extends CeilingSensorState {}
class CeilingLoadingInitialState extends CeilingSensorState {}
class CeilingUpdateState extends CeilingSensorState {
final CeilingSensorModel ceilingSensorModel;
const CeilingUpdateState({required this.ceilingSensorModel});
@override
List<Object> get props => [ceilingSensorModel];
}
class CeilingLoadingNewSate extends CeilingSensorState {
final CeilingSensorModel ceilingSensorModel;
const CeilingLoadingNewSate({required this.ceilingSensorModel});
@override
List<Object> get props => [ceilingSensorModel];
}
class CeilingFailedState extends CeilingSensorState {
final String error;
const CeilingFailedState({required this.error});
@override
List<Object> get props => [error];
}

View File

@ -0,0 +1,62 @@
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_status.dart';
class CeilingSensorModel {
String presenceState;
int sensitivity;
String checkingResult;
int presenceRange;
int sportsPara;
String bodyMovement;
int noBodyTime;
int maxDistance;
CeilingSensorModel(
{required this.presenceState,
required this.sensitivity,
required this.checkingResult,
required this.presenceRange,
required this.sportsPara,
required this.bodyMovement,
required this.noBodyTime,
required this.maxDistance});
factory CeilingSensorModel.fromJson(List<Status> jsonList) {
late String _presenceState;
late int _sensitivity;
late String _checkingResult;
int _presenceRange = 1;
int _sportsPara = 1;
String _bodyMovement = 'none';
int _noBodyTime = 0;
int _maxDis = 0;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'presence_state') {
_presenceState = jsonList[i].value ?? 'none';
} else if (jsonList[i].code == 'sensitivity') {
_sensitivity = jsonList[i].value ?? 1;
} else if (jsonList[i].code == 'checking_result') {
_checkingResult = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'presence_range') {
_presenceRange = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'sports_para') {
_sportsPara = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'body_movement') {
_bodyMovement = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'none_body_time') {
_noBodyTime = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'moving_max_dis') {
_maxDis = jsonList[i].value ?? 0;
}
}
return CeilingSensorModel(
presenceState: _presenceState,
sensitivity: _sensitivity,
checkingResult: _checkingResult,
presenceRange: _presenceRange,
sportsPara: _sportsPara,
bodyMovement: _bodyMovement,
noBodyTime: _noBodyTime,
maxDistance: _maxDis);
}
}

View File

@ -0,0 +1,123 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/bloc.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/event.dart';
import 'package:syncrow_web/pages/device_managment/ceiling_sensor/bloc/state.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_display_data.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_static_widget.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_status.dart';
import 'package:syncrow_web/pages/device_managment/shared/sensors_widgets/presence_update_data.dart';
import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
class CeilingSensorControls extends StatelessWidget with HelperResponsiveLayout {
const CeilingSensorControls({super.key, required this.device});
final AllDevicesModel device;
@override
Widget build(BuildContext context) {
final isLarge = isLargeScreenSize(context);
final isMedium = isMediumScreenSize(context);
return BlocProvider(
create: (context) =>
CeilingSensorBloc(deviceId: device.uuid ?? '')..add(CeilingInitialEvent()),
child: BlocBuilder<CeilingSensorBloc, CeilingSensorState>(
builder: (context, state) {
if (state is CeilingLoadingInitialState) {
return const Center(child: CircularProgressIndicator());
} else if (state is CeilingUpdateState) {
return GridView(
padding: const EdgeInsets.symmetric(horizontal: 50),
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: isLarge
? 3
: isMedium
? 2
: 1,
mainAxisExtent: 133,
crossAxisSpacing: 12,
mainAxisSpacing: 12,
),
children: [
PresenceState(
value: state.ceilingSensorModel.presenceState,
),
PresenceDisplayValue(
value: state.ceilingSensorModel.sportsPara.toString(),
postfix: '',
description: 'Sports para',
),
PresenceDisplayValue(
value: state.ceilingSensorModel.presenceRange.toString(),
postfix: 'm',
description: 'Detection Range',
),
PresenceUpdateData(
value: state.ceilingSensorModel.sensitivity.toDouble(),
title: 'Sensitivity:',
minValue: 1,
maxValue: 5,
steps: 1,
action: (int value) {
context.read<CeilingSensorBloc>().add(
CeilingChangeValueEvent(
code: 'sensitivity',
value: value,
),
);
},
),
PresenceUpdateData(
value: state.ceilingSensorModel.maxDistance.toDouble(),
title: 'Maximum Distance:',
minValue: 0,
maxValue: 500,
steps: 50,
description: 'm',
action: (int value) => context.read<CeilingSensorBloc>().add(
CeilingChangeValueEvent(
code: 'moving_max_dis',
value: value,
),
),
),
PresenceUpdateData(
value: (state.ceilingSensorModel.noBodyTime.toDouble() / 3600).roundToDouble(),
title: 'Nobody Time:',
minValue: 0,
maxValue: 300000,
steps: 5000,
description: 'hr',
action: (int value) =>
context.read<CeilingSensorBloc>().add(CeilingChangeValueEvent(
code: 'none_body_time',
value: value,
))),
GestureDetector(
onTap: () {},
child: const PresenceStaticWidget(
icon: Assets.illuminanceRecordIcon,
description: 'Presence Record',
),
),
GestureDetector(
onTap: () {},
child: const PresenceStaticWidget(
icon: Assets.helpDescriptionIcon,
description: 'Help Description',
),
),
],
);
} else {
return const Center(child: Text('Error fetching status'));
}
},
),
);
}
}