mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-11-27 10:14:55 +00:00
implemented ceiling and wall sensors, and bug fixes
This commit is contained in:
87
lib/pages/device_managment/ceiling_sensor/bloc/bloc.dart
Normal file
87
lib/pages/device_managment/ceiling_sensor/bloc/bloc.dart
Normal 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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
19
lib/pages/device_managment/ceiling_sensor/bloc/event.dart
Normal file
19
lib/pages/device_managment/ceiling_sensor/bloc/event.dart
Normal 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];
|
||||
}
|
||||
38
lib/pages/device_managment/ceiling_sensor/bloc/state.dart
Normal file
38
lib/pages/device_managment/ceiling_sensor/bloc/state.dart
Normal 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];
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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'));
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user