Implemented ceiling, wall sensors functionality

This commit is contained in:
Abdullah Alassaf
2024-05-22 23:55:35 +03:00
parent 008ba8be32
commit 44b08c482d
26 changed files with 1296 additions and 493 deletions

View File

@ -0,0 +1,48 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_state.dart';
import 'package:syncrow_app/features/devices/model/ceiling_sensor_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/status_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class CeilingSensorBloc extends Bloc<CeilingSensorEvent, CeilingSensorState> {
final String deviceId;
late DeviceModel deviceModel;
late CeilingSensorModel deviceStatus;
CeilingSensorBloc({required this.deviceId}) : super(InitialState()) {
on<InitialEvent>(_fetchCeilingSensorStatus);
on<ChangeValueEvent>(_changeValue);
}
void _fetchCeilingSensorStatus(InitialEvent event, Emitter<CeilingSensorState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(deviceId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = CeilingSensorModel.fromJson(statusModelList);
emit(UpdateState(ceilingSensorModel: deviceStatus));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeValue(ChangeValueEvent event, Emitter<CeilingSensorState> emit) async {
emit(LoadingNewSate(ceilingSensorModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: event.code, value: event.value), deviceId);
if (response['success'] ?? false) {
deviceStatus.sensitivity = event.value;
}
} catch (_) {}
emit(UpdateState(ceilingSensorModel: deviceStatus));
}
}

View File

@ -0,0 +1,21 @@
import 'package:equatable/equatable.dart';
abstract class CeilingSensorEvent extends Equatable {
const CeilingSensorEvent();
@override
List<Object> get props => [];
}
class LoadingEvent extends CeilingSensorEvent {}
class InitialEvent extends CeilingSensorEvent {}
class ChangeValueEvent extends CeilingSensorEvent {
final int value;
final String code;
const ChangeValueEvent({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_app/features/devices/model/ceiling_sensor_model.dart';
class CeilingSensorState extends Equatable {
const CeilingSensorState();
@override
List<Object> get props => [];
}
class InitialState extends CeilingSensorState {}
class LoadingInitialState extends CeilingSensorState {}
class UpdateState extends CeilingSensorState {
final CeilingSensorModel ceilingSensorModel;
const UpdateState({required this.ceilingSensorModel});
@override
List<Object> get props => [ceilingSensorModel];
}
class LoadingNewSate extends CeilingSensorState {
final CeilingSensorModel ceilingSensorModel;
const LoadingNewSate({required this.ceilingSensorModel});
@override
List<Object> get props => [ceilingSensorModel];
}
class FailedState extends CeilingSensorState {
final String error;
const FailedState({required this.error});
@override
List<Object> get props => [error];
}

View File

@ -0,0 +1,122 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/smart_door.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class SmartDoorBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
final String deviceId;
late SmartDoorModel deviceStatus;
SmartDoorBloc({required this.deviceId}) : super(InitialState()) {
on<InitialEvent>(_fetchThreeGangStatus);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
on<ChangeSecondSwitchStatusEvent>(_changeSecondSwitch);
on<ChangeThirdSwitchStatusEvent>(_changeThirdSwitch);
on<AllOffEvent>(_allOff);
on<AllOnEvent>(_allOn);
}
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(deviceId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = SmartDoorModel.fromJson(statusModelList);
emit(UpdateState(threeGangModel: deviceStatus));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_1', value: !event.value), deviceId);
if (response['success'] ?? false) {
deviceStatus.firstSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _changeSecondSwitch(
ChangeSecondSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_2', value: !event.value), deviceId);
if (response['success'] ?? false) {
deviceStatus.secondSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_3', value: !event.value), deviceId);
if (response['success'] ?? false) {
deviceStatus.thirdSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _allOff(AllOffEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_1', value: false), deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_2', value: false), deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_3', value: false), deviceId),
]);
if (response.every((element) => element['success'] ?? false)) {
deviceStatus.firstSwitch = false;
deviceStatus.secondSwitch = false;
deviceStatus.thirdSwitch = false;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _allOn(AllOnEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_1', value: true), deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_2', value: true), deviceId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'switch_3', value: true), deviceId),
]);
if (response.every((element) => element['success'] ?? false)) {
deviceStatus.firstSwitch = true;
deviceStatus.secondSwitch = true;
deviceStatus.thirdSwitch = true;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
}

View File

@ -0,0 +1,17 @@
import 'package:equatable/equatable.dart';
abstract class SmartDoorEvent extends Equatable {
const SmartDoorEvent();
@override
List<Object> get props => [];
}
class InitialEvent extends SmartDoorEvent {}
class UpdateLockEvent extends SmartDoorEvent {
final bool value;
const UpdateLockEvent({required this.value});
@override
List<Object> get props => [value];
}

View File

@ -0,0 +1,39 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/smart_door.dart';
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
class SmartDoorState extends Equatable {
const SmartDoorState();
@override
List<Object> get props => [];
}
class InitialState extends SmartDoorState {}
class LoadingInitialState extends SmartDoorState {}
class UpdateState extends SmartDoorState {
final SmartDoorModel smartDoorModel;
const UpdateState({required this.smartDoorModel});
@override
List<Object> get props => [smartDoorModel];
}
class LoadingNewSate extends SmartDoorState {
final SmartDoorModel smartDoorModel;
const LoadingNewSate({required this.smartDoorModel});
@override
List<Object> get props => [smartDoorModel];
}
class FailedState extends SmartDoorState {
final String error;
const FailedState({required this.error});
@override
List<Object> get props => [error];
}

View File

@ -1,22 +1,26 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_event.dart';
import 'package:syncrow_app/features/devices/bloc/three_gang_bloc/three_gang_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/features/devices/model/three_gang_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
final String threeGangId;
late DeviceModel deviceModel;
late ThreeGangModel deviceStatus;
ThreeGangBloc({required this.threeGangId}) : super(InitialState()) {
on<InitialEvent>(_fetchThreeGangStatus);
on<ChangeFirstSwitchStatusEvent>(_changeFirstSwitch);
on<ChangeSecondSwitchStatusEvent>(_changeSecondSwitch);
on<ChangeThirdSwitchStatusEvent>(_changeThirdSwitch);
on<AllOffEvent>(_allOff);
on<AllOnEvent>(_allOn);
}
void _fetchThreeGangStatus(InitialEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingState());
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(threeGangId);
List<StatusModel> statusModelList = [];
@ -30,4 +34,91 @@ class ThreeGangBloc extends Bloc<ThreeGangEvent, ThreeGangState> {
return;
}
}
void _changeFirstSwitch(ChangeFirstSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_1', value: !event.value),
threeGangId);
if (response['success'] ?? false) {
deviceStatus.firstSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _changeSecondSwitch(
ChangeSecondSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_2', value: !event.value),
threeGangId);
if (response['success'] ?? false) {
deviceStatus.secondSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _changeThirdSwitch(ChangeThirdSwitchStatusEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_3', value: !event.value),
threeGangId);
if (response['success'] ?? false) {
deviceStatus.thirdSwitch = !event.value;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _allOff(AllOffEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_1', value: false), threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_2', value: false), threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_3', value: false), threeGangId),
]);
if (response.every((element) => element['success'] ?? false)) {
deviceStatus.firstSwitch = false;
deviceStatus.secondSwitch = false;
deviceStatus.thirdSwitch = false;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
void _allOn(AllOnEvent event, Emitter<ThreeGangState> emit) async {
emit(LoadingNewSate(threeGangModel: deviceStatus));
try {
final response = await Future.wait([
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_1', value: true), threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_2', value: true), threeGangId),
DevicesAPI.controlDevice(
DeviceControlModel(deviceId: threeGangId, code: 'switch_3', value: true), threeGangId),
]);
if (response.every((element) => element['success'] ?? false)) {
deviceStatus.firstSwitch = true;
deviceStatus.secondSwitch = true;
deviceStatus.thirdSwitch = true;
}
} catch (_) {}
emit(UpdateState(threeGangModel: deviceStatus));
}
}

View File

@ -11,4 +11,27 @@ class LoadingEvent extends ThreeGangEvent {}
class InitialEvent extends ThreeGangEvent {}
class ChangeStatusEvent extends ThreeGangEvent {}
class ChangeFirstSwitchStatusEvent extends ThreeGangEvent {
final bool value;
const ChangeFirstSwitchStatusEvent({required this.value});
@override
List<Object> get props => [value];
}
class ChangeSecondSwitchStatusEvent extends ThreeGangEvent {
final bool value;
const ChangeSecondSwitchStatusEvent({required this.value});
@override
List<Object> get props => [value];
}
class ChangeThirdSwitchStatusEvent extends ThreeGangEvent {
final bool value;
const ChangeThirdSwitchStatusEvent({required this.value});
@override
List<Object> get props => [value];
}
class AllOffEvent extends ThreeGangEvent {}
class AllOnEvent extends ThreeGangEvent {}

View File

@ -10,7 +10,7 @@ class ThreeGangState extends Equatable {
class InitialState extends ThreeGangState {}
class LoadingState extends ThreeGangState {}
class LoadingInitialState extends ThreeGangState {}
class UpdateState extends ThreeGangState {
final ThreeGangModel threeGangModel;
@ -20,6 +20,14 @@ class UpdateState extends ThreeGangState {
List<Object> get props => [threeGangModel];
}
class LoadingNewSate extends ThreeGangState {
final ThreeGangModel threeGangModel;
const LoadingNewSate({required this.threeGangModel});
@override
List<Object> get props => [threeGangModel];
}
class FailedState extends ThreeGangState {
final String error;

View File

@ -0,0 +1,68 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.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/wall_sensor_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
final String deviceId;
late DeviceModel deviceModel;
late WallSensorModel deviceStatus;
WallSensorBloc({required this.deviceId}) : super(InitialState()) {
on<InitialEvent>(_fetchCeilingSensorStatus);
on<ChangeIndicatorEvent>(_changeIndicator);
on<ChangeValueEvent>(_changeValue);
}
void _fetchCeilingSensorStatus(InitialEvent event, Emitter<WallSensorState> emit) async {
emit(LoadingInitialState());
try {
var response = await DevicesAPI.getDeviceStatus(deviceId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = WallSensorModel.fromJson(statusModelList);
emit(UpdateState(wallSensorModel: deviceStatus));
} catch (e) {
emit(FailedState(error: e.toString()));
return;
}
}
void _changeIndicator(ChangeIndicatorEvent event, Emitter<WallSensorState> emit) async {
emit(LoadingNewSate(wallSensorModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: 'indicator', value: !event.value), deviceId);
if (response['success'] ?? false) {
deviceStatus.indicator = !event.value;
}
} catch (_) {}
emit(UpdateState(wallSensorModel: deviceStatus));
}
void _changeValue(ChangeValueEvent event, Emitter<WallSensorState> emit) async {
emit(LoadingNewSate(wallSensorModel: deviceStatus));
try {
final response = await DevicesAPI.controlDevice(
DeviceControlModel(deviceId: deviceId, code: event.code, value: event.value), deviceId);
if (response['success'] ?? false) {
if (event.code == 'far_detection') {
deviceStatus.farDetection = event.value;
} else if (event.code == 'motionless_sensitivity') {
deviceStatus.motionlessSensitivity = event.value;
} else if (event.code == 'motion_sensitivity_value') {
deviceStatus.motionSensitivity = event.value;
}
}
} catch (_) {}
emit(UpdateState(wallSensorModel: deviceStatus));
}
}

View File

@ -0,0 +1,29 @@
import 'package:equatable/equatable.dart';
abstract class WallSensorEvent extends Equatable {
const WallSensorEvent();
@override
List<Object> get props => [];
}
class LoadingEvent extends WallSensorEvent {}
class InitialEvent extends WallSensorEvent {}
class ChangeIndicatorEvent extends WallSensorEvent {
final bool value;
const ChangeIndicatorEvent({required this.value});
@override
List<Object> get props => [value];
}
class ChangeValueEvent extends WallSensorEvent {
final int value;
final String code;
const ChangeValueEvent({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_app/features/devices/model/wall_sensor_model.dart';
class WallSensorState extends Equatable {
const WallSensorState();
@override
List<Object> get props => [];
}
class InitialState extends WallSensorState {}
class LoadingInitialState extends WallSensorState {}
class UpdateState extends WallSensorState {
final WallSensorModel wallSensorModel;
const UpdateState({required this.wallSensorModel});
@override
List<Object> get props => [wallSensorModel];
}
class LoadingNewSate extends WallSensorState {
final WallSensorModel wallSensorModel;
const LoadingNewSate({required this.wallSensorModel});
@override
List<Object> get props => [wallSensorModel];
}
class FailedState extends WallSensorState {
final String error;
const FailedState({required this.error});
@override
List<Object> get props => [error];
}

View File

@ -0,0 +1,31 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class CeilingSensorModel {
String presenceState;
int sensitivity;
String checkingResult;
CeilingSensorModel({
required this.presenceState,
required this.sensitivity,
required this.checkingResult,
});
factory CeilingSensorModel.fromJson(List<StatusModel> jsonList) {
late String _presenceState;
late int _sensitivity;
late String _checkingResult;
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 ?? false;
} else if (jsonList[i].code == 'checking_result') {
_checkingResult = jsonList[i].value ?? false;
}
}
return CeilingSensorModel(
presenceState: _presenceState, sensitivity: _sensitivity, checkingResult: _checkingResult);
}
}

View File

@ -0,0 +1,116 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class SmartDoorModel {
String unlockFingerprint;
int unlockPassword;
int unlockTemporary;
int unlockCard;
String unlockAlarm;
int unlockRequest;
int residualElectricity;
bool reverseLock;
int unlockApp;
bool hijack;
bool doorbell;
String unlockOfflinePd;
String unlockOfflineClear;
String unlockDoubleKit;
String remoteNoPdSetkey;
String remoteNoDpKey;
bool normalOpenSwitch;
SmartDoorModel(
{required this.unlockFingerprint,
required this.unlockPassword,
required this.unlockTemporary,
required this.unlockCard,
required this.unlockAlarm,
required this.unlockRequest,
required this.residualElectricity,
required this.reverseLock,
required this.unlockApp,
required this.hijack,
required this.doorbell,
required this.unlockOfflinePd,
required this.unlockOfflineClear,
required this.unlockDoubleKit,
required this.remoteNoPdSetkey,
required this.remoteNoDpKey,
required this.normalOpenSwitch});
factory SmartDoorModel.fromJson(List<StatusModel> jsonList) {
late String _unlockFingerprint;
late int _unlockPassword;
late int _unlockTemporary;
late int _unlockCard;
late String _unlockAlarm;
late int _unlockRequest;
late int _residualElectricity;
late bool _reverseLock;
late int _unlockApp;
late bool _hijack;
late bool _doorbell;
late String _unlockOfflinePd;
late String _unlockOfflineClear;
late String _unlockDoubleKit;
late String _remoteNoPdSetkey;
late String _remoteNoDpKey;
late bool _normalOpenSwitch;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'unlock_fingerprint') {
_unlockFingerprint = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'unlock_password') {
_unlockPassword = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'unlock_temporary') {
_unlockTemporary = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'unlock_card') {
_unlockCard = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'alarm_lock') {
_unlockAlarm = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'unlock_request') {
_unlockRequest = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'residual_electricity') {
_residualElectricity = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'reverse_lock') {
_reverseLock = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'unlock_app') {
_unlockApp = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'hijack') {
_hijack = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'doorbell') {
_doorbell = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'unlock_offline_pd') {
_unlockOfflinePd = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'unlock_offline_clear') {
_unlockOfflineClear = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'unlock_double_kit') {
_unlockDoubleKit = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'remote_no_pd_setkey') {
_remoteNoPdSetkey = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'remote_no_dp_key') {
_remoteNoDpKey = jsonList[i].value ?? '';
} else if (jsonList[i].code == 'normal_open_switch') {
_normalOpenSwitch = jsonList[i].value ?? false;
}
}
return SmartDoorModel(
unlockFingerprint: _unlockFingerprint,
unlockPassword: _unlockPassword,
unlockTemporary: _unlockTemporary,
unlockCard: _unlockCard,
unlockAlarm: _unlockAlarm,
unlockRequest: _unlockRequest,
residualElectricity: _residualElectricity,
reverseLock: _reverseLock,
unlockApp: _unlockApp,
hijack: _hijack,
doorbell: _doorbell,
unlockOfflinePd: _unlockOfflinePd,
unlockOfflineClear: _unlockOfflineClear,
unlockDoubleKit: _unlockDoubleKit,
remoteNoPdSetkey: _remoteNoPdSetkey,
remoteNoDpKey: _remoteNoDpKey,
normalOpenSwitch: _normalOpenSwitch);
}
}

View File

@ -0,0 +1,63 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class WallSensorModel {
String presenceState;
int farDetection;
int presenceTime;
int motionSensitivity;
int motionlessSensitivity;
int currentDistance;
int illuminance;
bool 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,
});
factory WallSensorModel.fromJson(List<StatusModel> jsonList) {
late String _presenceState;
late int _farDetection;
late int _presenceTime;
late int _motionSensitivity;
late int _motionlessSensitivity;
late int _currentDistance;
late int _illuminance;
late bool _indicator;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'presence_state') {
_presenceState = jsonList[i].value ?? 'none';
} else if (jsonList[i].code == 'far_detection') {
_farDetection = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'presence_time') {
_presenceTime = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'motion_sensitivity_value') {
_motionSensitivity = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'motionless_sensitivity') {
_motionlessSensitivity = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'dis_current') {
_currentDistance = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'illuminance_value') {
_illuminance = jsonList[i].value ?? 0;
} else if (jsonList[i].code == 'indicator') {
_indicator = jsonList[i].value ?? 0;
}
}
return WallSensorModel(
presenceState: _presenceState,
farDetection: _farDetection,
presenceTime: _presenceTime,
motionSensitivity: _motionSensitivity,
motionlessSensitivity: _motionlessSensitivity,
currentDistance: _currentDistance,
illuminance: _illuminance,
indicator: _indicator);
}
}

View File

@ -6,7 +6,6 @@ import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_controls.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/ac_interface_temp_unit.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
class AcInterface extends StatelessWidget {
const AcInterface({super.key, required this.ac});

View File

@ -0,0 +1,288 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/ceiling_bloc/ceiling_sensor_state.dart';
import 'package:syncrow_app/features/devices/model/ceiling_sensor_model.dart';
import 'package:syncrow_app/features/devices/model/device_model.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';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/helpers/misc_string_helpers.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
import '../wall_sensor/wall_sensor_interface.dart';
class CeilingSensorInterface extends StatelessWidget {
const CeilingSensorInterface({super.key, required this.ceilingSensor});
final DeviceModel ceilingSensor;
@override
Widget build(BuildContext context) {
// String state = ceilingSensor.status
// .firstWhere((element) => element.code == "presence_state")
// .value
// .toString();
return BlocProvider(
create: (context) =>
CeilingSensorBloc(deviceId: ceilingSensor.uuid ?? '')..add(InitialEvent()),
child: BlocBuilder<CeilingSensorBloc, CeilingSensorState>(builder: (context, state) {
CeilingSensorModel ceilingSensorModel =
CeilingSensorModel(presenceState: 'none', sensitivity: 1, checkingResult: '');
if (state is UpdateState) {
ceilingSensorModel = state.ceilingSensorModel;
} else if (state is LoadingNewSate) {
ceilingSensorModel = state.ceilingSensorModel;
}
return AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
statusBarIconBrightness: Brightness.light,
),
child: SafeArea(
child: Scaffold(
backgroundColor: ColorsManager.backgroundColor,
extendBodyBehindAppBar: true,
extendBody: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
title: BodyLarge(
text: ceilingSensor.name ?? "",
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
),
body: state is LoadingInitialState
? const Center(
child: RefreshProgressIndicator(),
)
: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
padding: const EdgeInsets.all(Constants.defaultPadding),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
Assets.assetsImagesBackground,
),
fit: BoxFit.cover,
opacity: 0.4,
),
),
child: Column(
children: [
const Spacer(),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
if ((ceilingSensor.isOnline ?? false) == false) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Device is offline',
),
backgroundColor: Colors.red,
),
);
return;
}
String controlCode = 'sensitivity';
showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Sensitivity',
sensor: ceilingSensor,
controlCode: controlCode,
value: ceilingSensor.status
.firstWhere((element) => element.code == controlCode)
.value as int,
min: ceilingSensor.functions
.firstWhere((element) => element.code == controlCode)
.values
?.min ??
0,
max: ceilingSensor.functions
.firstWhere((element) => element.code == controlCode)
.values
?.max ??
0,
),
);
},
child: SvgPicture.asset(
state == 'presence'
? Assets.assetsIconsPresenceSensorAssetsPresence
: Assets.assetsIconsPresenceSensorAssetsPresenceSensorMotion,
width: 100,
height: 100,
// colorFilter: ColorFilter.mode(
// (ceilingSensor.isOnline ?? false)
// ? ColorsManager.primaryColor
// : Colors.grey.withOpacity(0.9),
// BlendMode.srcIn,
// ),
),
),
const SizedBox(
height: 10,
),
BodyMedium(
text: StringHelpers.toTitleCase(ceilingSensorModel.presenceState),
// (ceilingSensor.isOnline ?? false)
// ? StringHelpers.toTitleCase(ceilingSensor.status
// .firstWhere((element) =>
// element.code == 'presence_state')
// .value
// .toString())
// : "Offline",
style: context.bodyMedium.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
const Spacer(),
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
DefaultContainer(
padding:
const EdgeInsets.symmetric(vertical: 20, horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodySmall(text: 'Sports Para'),
BodyLarge(
text: '0',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Container(
width: 1,
height: 45,
color: ColorsManager.greyColor,
),
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodySmall(text: 'Detection Range'),
BodyLarge(
text: '0.0M',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Container(
width: 1,
height: 45,
color: ColorsManager.greyColor,
),
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodySmall(text: 'Movement'),
BodyLarge(
text: 'none',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
],
)),
const SizedBox(
height: 15,
),
...List.generate(
ceilingSensorButtons.length,
(index) => DefaultContainer(
margin: const EdgeInsets.only(bottom: 5),
padding:
const EdgeInsets.symmetric(vertical: 12, horizontal: 20),
onTap: () {
if (ceilingSensorButtons[index]['page'] != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ceilingSensorButtons[index]['page'] as Widget,
),
);
}
},
child: Row(
children: [
SvgPicture.asset(
ceilingSensorButtons[index]['icon'] as String,
// width: 30,
// height: 50,
),
const SizedBox(
width: 25,
),
BodyMedium(
text: ceilingSensorButtons[index]['title'] as String,
style: context.bodyMedium.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
),
),
],
),
),
],
)),
),
),
);
}),
);
}
}
var ceilingSensorButtons = [
{
'title': 'Parameter Settings',
'icon': Assets.assetsIconsPresenceSensorAssetsParameterSettings,
'page': null,
},
{
'title': 'Induction History',
'icon': Assets.assetsIconsPresenceSensorAssetsInductionRecording,
'page': null,
},
{
'title': 'Help Description',
'icon': Assets.assetsIconsPresenceSensorAssetsHelpDescription,
'page': null,
},
];

View File

@ -1,4 +1,4 @@
part of 'wall_sensor_interface.dart';
part of '../wall_sensor/wall_sensor_interface.dart';
class ParameterControlDialog extends StatefulWidget {
final String title;
@ -127,8 +127,7 @@ class ParameterControlDialogState extends State<ParameterControlDialog> {
child: Center(
child: BodyMedium(
text: 'Cancel',
style: context.bodyMedium
.copyWith(color: ColorsManager.greyColor),
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
),
),
),
@ -141,24 +140,26 @@ class ParameterControlDialogState extends State<ParameterControlDialog> {
onTap: () {
Navigator.pop(context, _value);
if (widget.sensor.isOnline == null) {
CustomSnackBar.displaySnackBar('The device is offline');
return;
}
if (!widget.sensor.isOnline!) {
CustomSnackBar.displaySnackBar('The device is offline');
return;
}
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: widget.sensor.uuid,
code: widget.controlCode,
value: widget.value),
widget.sensor.uuid ?? '');
// DevicesCubit.getInstance().deviceControl(
// DeviceControlModel(
// deviceId: widget.sensor.uuid,
// code: widget.controlCode,
// value: widget.value),
// widget.sensor.uuid ?? '');
},
child: Center(
child: BodyMedium(
text: 'Confirm',
style: context.bodyMedium.copyWith(
color: ColorsManager.primaryColorWithOpacity),
style:
context.bodyMedium.copyWith(color: ColorsManager.primaryColorWithOpacity),
),
),
),

View File

@ -1,275 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/model/device_model.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';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/helpers/misc_string_helpers.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
import 'wall_sensor_interface.dart';
class CeilingSensorInterface extends StatelessWidget {
const CeilingSensorInterface({super.key, required this.ceilingSensor});
final DeviceModel ceilingSensor;
@override
Widget build(BuildContext context) {
String state = ceilingSensor.status
.firstWhere((element) => element.code == "presence_state")
.value
.toString();
return AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
statusBarIconBrightness: Brightness.light,
),
child: SafeArea(
child: Scaffold(
backgroundColor: ColorsManager.backgroundColor,
extendBodyBehindAppBar: true,
extendBody: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
title: BodyLarge(
text: ceilingSensor.name ?? "",
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
padding: const EdgeInsets.all(Constants.defaultPadding),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
Assets.assetsImagesBackground,
),
fit: BoxFit.cover,
opacity: 0.4,
),
),
child: Column(
children: [
const Spacer(),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
if ((ceilingSensor.isOnline ?? false) == false) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text(
'Device is offline',
),
backgroundColor: Colors.red,
),
);
return;
}
String controlCode = 'sensitivity';
showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Sensitivity',
sensor: ceilingSensor,
controlCode: controlCode,
value: ceilingSensor.status
.firstWhere(
(element) => element.code == controlCode)
.value as int,
min: ceilingSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.values
?.min ??
0,
max: ceilingSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.values
?.max ??
0,
),
);
},
child: SvgPicture.asset(
state == 'presence'
? Assets.assetsIconsPresenceSensorAssetsPresence
: Assets
.assetsIconsPresenceSensorAssetsPresenceSensorMotion,
width: 100,
height: 100,
// colorFilter: ColorFilter.mode(
// (ceilingSensor.isOnline ?? false)
// ? ColorsManager.primaryColor
// : Colors.grey.withOpacity(0.9),
// BlendMode.srcIn,
// ),
),
),
const SizedBox(
height: 10,
),
BodyMedium(
text: StringHelpers.toTitleCase(state),
// (ceilingSensor.isOnline ?? false)
// ? StringHelpers.toTitleCase(ceilingSensor.status
// .firstWhere((element) =>
// element.code == 'presence_state')
// .value
// .toString())
// : "Offline",
style: context.bodyMedium.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
const Spacer(),
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: [
DefaultContainer(
padding: const EdgeInsets.symmetric(
vertical: 20, horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodySmall(text: 'Sports Para'),
BodyLarge(
text: '0',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10),
child: Container(
width: 1,
height: 45,
color: ColorsManager.greyColor,
),
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodySmall(text: 'Detection Range'),
BodyLarge(
text: '0.0M',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10),
child: Container(
width: 1,
height: 45,
color: ColorsManager.greyColor,
),
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
const BodySmall(text: 'Movement'),
BodyLarge(
text: 'none',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
],
)),
const SizedBox(
height: 15,
),
...List.generate(
ceilingSensorButtons.length,
(index) => DefaultContainer(
margin: const EdgeInsets.only(bottom: 5),
padding: const EdgeInsets.symmetric(
vertical: 12, horizontal: 20),
onTap: () {
if (ceilingSensorButtons[index]['page'] != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ceilingSensorButtons[index]['page']
as Widget,
),
);
}
},
child: Row(
children: [
SvgPicture.asset(
ceilingSensorButtons[index]['icon'] as String,
// width: 30,
// height: 50,
),
const SizedBox(
width: 25,
),
BodyMedium(
text: ceilingSensorButtons[index]['title']
as String,
style: context.bodyMedium.copyWith(
fontWeight: FontsManager.bold,
),
),
],
),
),
),
],
),
),
],
)),
),
),
);
}
}
var ceilingSensorButtons = [
{
'title': 'Parameter Settings',
'icon': Assets.assetsIconsPresenceSensorAssetsParameterSettings,
'page': null,
},
{
'title': 'Induction History',
'icon': Assets.assetsIconsPresenceSensorAssetsInductionRecording,
'page': null,
},
{
'title': 'Help Description',
'icon': Assets.assetsIconsPresenceSensorAssetsHelpDescription,
'page': null,
},
];

View File

@ -1,74 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/devices_cubit.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/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';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/helpers/misc_string_helpers.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
part "parameters_list.dart";
part "presence_indicator.dart";
part "parameter_control_dialog.dart";
class WallMountedInterface extends StatelessWidget {
const WallMountedInterface({super.key, required this.wallSensor});
final DeviceModel wallSensor;
@override
Widget build(BuildContext context) {
return AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
statusBarIconBrightness: Brightness.light,
),
child: SafeArea(
child: Scaffold(
backgroundColor: ColorsManager.backgroundColor,
extendBodyBehindAppBar: true,
extendBody: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
title: BodyLarge(
text: wallSensor.name ?? "",
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
padding: const EdgeInsets.all(Constants.defaultPadding),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
Assets.assetsImagesBackground,
),
fit: BoxFit.cover,
opacity: 0.4,
),
),
child: Column(
children: [
PresenceIndicator(
wallSensor: wallSensor,
),
ParametersList(wallSensor: wallSensor),
],
),
),
),
),
);
}
}

View File

@ -10,8 +10,8 @@ import 'package:syncrow_app/features/devices/bloc/devices_cubit.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/ACs/acs_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/presence_sensors/wall_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/presence_sensors/ceiling_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/wall_sensor/wall_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/ceiling_sensor/ceiling_sensor_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/smart_door/door_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/three_gang/three_gang_interface.dart';
import 'package:syncrow_app/features/shared_widgets/custom_switch.dart';
@ -90,10 +90,20 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
// navigateToInterface(ACsView(deviceModel: device), context);
break;
case DeviceType.WallSensor:
navigateToInterface(WallMountedInterface(wallSensor: device), context);
// navigateToInterface(WallMountedInterface(wallSensor: device), context);
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
WallMountedInterface(deviceModel: device)));
break;
case DeviceType.CeilingSensor:
navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
CeilingSensorInterface(ceilingSensor: device)));
// navigateToInterface(CeilingSensorInterface(ceilingSensor: device), context);
break;
case DeviceType.Curtain:
break;

View File

@ -8,56 +8,49 @@ import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class GangSwitch extends StatelessWidget {
const GangSwitch({
super.key,
required this.threeGangSwitch,
required this.value,
});
const GangSwitch(
{super.key, required this.threeGangSwitch, required this.value, required this.action});
final DeviceModel threeGangSwitch;
final bool value;
final Function action;
@override
Widget build(BuildContext context) {
return BlocBuilder<ThreeGangBloc, ThreeGangState>(
builder: (context, state) {
return InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () {
// var tempControl = DeviceControlModel(
// deviceId: control.deviceId, code: control.code!, value: !control.value!);
// DevicesCubit.getInstance().deviceControl(
// tempControl,
// control.deviceId!,
// );
},
child: Stack(
alignment: value ? Alignment.topCenter : Alignment.bottomCenter,
children: [
Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(100.0)),
color:
value ? ColorsManager.primaryColorWithOpacity : ColorsManager.switchOffColor,
),
width: 60,
height: 115,
),
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox.square(
dimension: 60,
child: SvgPicture.asset(
value ? Assets.assetsIconsLightSwitchOn : Assets.assetsIconsLightSwitchOff,
fit: BoxFit.fill,
),
),
),
],
),
);
return InkWell(
overlayColor: MaterialStateProperty.all(Colors.transparent),
onTap: () {
action();
// var tempControl = DeviceControlModel(
// deviceId: control.deviceId, code: control.code!, value: !control.value!);
// DevicesCubit.getInstance().deviceControl(
// tempControl,
// control.deviceId!,
// );
},
child: Stack(
alignment: value ? Alignment.topCenter : Alignment.bottomCenter,
children: [
Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(100.0)),
color: value ? ColorsManager.primaryColorWithOpacity : ColorsManager.switchOffColor,
),
width: 60,
height: 115,
),
Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox.square(
dimension: 60,
child: SvgPicture.asset(
value ? Assets.assetsIconsLightSwitchOn : Assets.assetsIconsLightSwitchOff,
fit: BoxFit.fill,
),
),
),
],
),
);
}
}

View File

@ -32,10 +32,12 @@ class ThreeGangScreen extends StatelessWidget {
firstCountDown: 0,
secondCountDown: 0,
thirdCountDown: 0);
if (state is UpdateState) {
if (state is LoadingNewSate) {
threeGangModel = state.threeGangModel;
} else if (state is UpdateState) {
threeGangModel = state.threeGangModel;
}
return state is LoadingState
return state is LoadingInitialState
? const Center(
child:
DefaultContainer(width: 50, height: 50, child: CircularProgressIndicator()),
@ -54,6 +56,11 @@ class ThreeGangScreen extends StatelessWidget {
GangSwitch(
threeGangSwitch: device,
value: threeGangModel.firstSwitch,
action: () {
BlocProvider.of<ThreeGangBloc>(context).add(
ChangeFirstSwitchStatusEvent(
value: threeGangModel.firstSwitch));
},
// control: DeviceControlModel(
// deviceId: device.uuid,
// // code: 'switch_1',
@ -78,6 +85,11 @@ class ThreeGangScreen extends StatelessWidget {
GangSwitch(
threeGangSwitch: device,
value: threeGangModel.secondSwitch,
action: () {
BlocProvider.of<ThreeGangBloc>(context).add(
ChangeSecondSwitchStatusEvent(
value: threeGangModel.secondSwitch));
},
// control: DeviceControlModel(
// // deviceId: 'bfe10693d4fd263206ocq9',
// // code: 'switch_2',
@ -103,6 +115,11 @@ class ThreeGangScreen extends StatelessWidget {
GangSwitch(
threeGangSwitch: device,
value: threeGangModel.thirdSwitch,
action: () {
BlocProvider.of<ThreeGangBloc>(context).add(
ChangeThirdSwitchStatusEvent(
value: threeGangModel.thirdSwitch));
},
),
const SizedBox(height: 20),
const SizedBox(
@ -157,6 +174,7 @@ class ThreeGangScreen extends StatelessWidget {
// ),
// device.uuid!,
// );
BlocProvider.of<ThreeGangBloc>(context).add(AllOnEvent());
},
child: Stack(
alignment: Alignment.center,
@ -287,6 +305,7 @@ class ThreeGangScreen extends StatelessWidget {
// ),
// device.uuid!,
// );
BlocProvider.of<ThreeGangBloc>(context).add(AllOffEvent());
},
child: Stack(
alignment: Alignment.center,

View File

@ -4,9 +4,11 @@ class ParametersList extends StatelessWidget {
const ParametersList({
super.key,
required this.wallSensor,
required this.presenceSensorsModel,
});
final DeviceModel wallSensor;
final WallSensorModel presenceSensorsModel;
@override
Widget build(BuildContext context) {
return Expanded(
@ -23,41 +25,39 @@ class ParametersList extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
DefaultContainer(
padding: const EdgeInsets.symmetric(
vertical: 12, horizontal: 15),
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
InkWell(
onTap: () {
onTap: () async {
if ((wallSensor.isOnline ?? false) == false) {
return;
}
String controlCode = 'motion_sensitivity_value';
showDialog(
final result = await showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Motion Detection Sensitivity',
sensor: wallSensor,
controlCode: controlCode,
value: wallSensor.status
.firstWhere((element) =>
element.code == controlCode)
.value as int,
value: presenceSensorsModel.motionSensitivity,
min: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.min ??
0,
max: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.max ??
0,
),
);
if (result != null) {
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeValueEvent(value: result, code: controlCode));
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -67,14 +67,8 @@ class ParametersList extends StatelessWidget {
text: 'Motion\nDetection\nSensitivity',
textAlign: TextAlign.center),
BodyLarge(
text: wallSensor.status
.firstWhere((element) =>
element.code ==
'motion_sensitivity_value')
.value
.toString(),
style: context.bodyLarge
.copyWith(fontWeight: FontsManager.bold),
text: presenceSensorsModel.motionSensitivity.toString(),
style: context.bodyLarge.copyWith(fontWeight: FontsManager.bold),
),
],
),
@ -88,35 +82,35 @@ class ParametersList extends StatelessWidget {
),
),
InkWell(
onTap: () {
onTap: () async {
if ((wallSensor.isOnline ?? false) == false) {
return;
}
String controlCode = 'motionless_sensitivity';
showDialog(
final result = await showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Motionless Detection Sensitivity',
sensor: wallSensor,
controlCode: controlCode,
value: wallSensor.status
.firstWhere((element) =>
element.code == controlCode)
.value as int,
value: presenceSensorsModel.motionlessSensitivity,
min: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.min ??
0,
max: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.max ??
0,
),
);
if (result != null) {
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeValueEvent(value: result, code: controlCode));
}
},
child: Column(
mainAxisSize: MainAxisSize.min,
@ -126,12 +120,7 @@ class ParametersList extends StatelessWidget {
text: 'Motionless\nDetection\nSensitivity',
textAlign: TextAlign.center),
BodyLarge(
text: wallSensor.status
.firstWhere((element) =>
element.code ==
'motionless_sensitivity')
.value
.toString(),
text: presenceSensorsModel.motionlessSensitivity.toString(),
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
@ -148,46 +137,44 @@ class ParametersList extends StatelessWidget {
),
),
InkWell(
onTap: () {
onTap: () async {
if ((wallSensor.isOnline ?? false) == false) {
return;
}
String controlCode = 'far_detection';
showDialog(
final result = await showDialog(
context: context,
builder: (context) => ParameterControlDialog(
title: 'Far Detection',
sensor: wallSensor,
controlCode: controlCode,
value: wallSensor.status
.firstWhere((element) =>
element.code == controlCode)
.value as int,
value: presenceSensorsModel.farDetection,
min: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.min ??
0,
max: wallSensor.functions
.firstWhere((element) =>
element.code == controlCode)
.firstWhere((element) => element.code == controlCode)
.values
?.max ??
0,
),
);
if (result != null) {
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeValueEvent(value: result, code: controlCode));
}
},
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const BodySmall(
text: 'Far\nDetection',
textAlign: TextAlign.center),
text: 'Far\nDetection', textAlign: TextAlign.center),
BodyLarge(
text:
'${wallSensor.status.firstWhere((element) => element.code == 'far_detection').value.toString()}${wallSensor.functions.firstWhere((element) => element.code == 'far_detection').values?.unit ?? ''}',
'${presenceSensorsModel.farDetection.toString()}${wallSensor.functions.firstWhere((element) => element.code == 'far_detection').values?.unit ?? ''}',
style: context.bodyLarge.copyWith(
fontWeight: FontsManager.bold,
),
@ -198,11 +185,11 @@ class ParametersList extends StatelessWidget {
],
),
),
listItem(wallSensorButtons[index], context, wallSensor)
listItem(wallSensorButtons[index], context, wallSensor, presenceSensorsModel)
],
);
}
return listItem(wallSensorButtons[index], context, wallSensor);
return listItem(wallSensorButtons[index], context, wallSensor, presenceSensorsModel);
},
),
),
@ -251,21 +238,26 @@ class ParametersList extends StatelessWidget {
];
}
Widget listItem(
Map<String, Object?> wallSensorButton,
BuildContext context,
DeviceModel wallSensor,
) {
Widget listItem(Map<String, Object?> wallSensorButton, BuildContext context, DeviceModel wallSensor,
WallSensorModel wallSensorStatus) {
String? unit;
dynamic value;
if (wallSensorButton['code'] != null) {
if (wallSensor.status
.any((element) => element.code == wallSensorButton['code'] as String)) {
// if (wallSensor.status.any((element) => element.code == wallSensorButton['code'] as String)) {
// unit = unitsMap[wallSensorButton['code'] as String];
// value = wallSensor.status
// .firstWhere((element) => element.code == wallSensorButton['code'] as String)
// .value;
// }
if (wallSensorButton['code'] == 'presence_time') {
unit = unitsMap[wallSensorButton['code'] as String];
value = wallSensor.status
.firstWhere(
(element) => element.code == wallSensorButton['code'] as String)
.value;
value = wallSensorStatus.presenceTime;
} else if (wallSensorButton['code'] == 'dis_current') {
unit = unitsMap[wallSensorButton['code'] as String];
value = wallSensorStatus.currentDistance;
} else if (wallSensorButton['code'] == 'illuminance_value') {
unit = unitsMap[wallSensorButton['code'] as String];
value = wallSensorStatus.illuminance;
}
}
return DefaultContainer(
@ -297,8 +289,7 @@ Widget listItem(
if (wallSensorButton['title'] != 'Indicator')
BodyMedium(
text: '${value ?? 'N/A'}${unit ?? ''}',
style:
context.bodyMedium.copyWith(color: ColorsManager.greyColor),
style: context.bodyMedium.copyWith(color: ColorsManager.greyColor),
),
if (wallSensorButton['title'] == 'Indicator')
Expanded(
@ -308,16 +299,11 @@ Widget listItem(
Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: value ?? false,
value: wallSensorStatus.indicator,
onChanged: (value) {
if (wallSensor.isOnline ?? false) {
DevicesCubit.getInstance().deviceControl(
DeviceControlModel(
deviceId: wallSensor.uuid,
code: 'indicator',
value: value,
),
wallSensor.uuid ?? '');
BlocProvider.of<WallSensorBloc>(context)
.add(ChangeIndicatorEvent(value: wallSensorStatus.indicator));
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(

View File

@ -1,14 +1,14 @@
part of "wall_sensor_interface.dart";
class PresenceIndicator extends StatelessWidget {
const PresenceIndicator({super.key, required this.wallSensor});
final DeviceModel wallSensor;
const PresenceIndicator({super.key, required this.state});
final String state;
@override
Widget build(BuildContext context) {
String state = wallSensor.status
.firstWhere((element) => element.code == "presence_state")
.value
.toString();
// String state = wallSensor.status
// .firstWhere((element) => element.code == "presence_state")
// .value
// .toString();
return Expanded(
flex: 6,
child: Column(

View File

@ -0,0 +1,104 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_state.dart';
import 'package:syncrow_app/features/devices/bloc/wall_sensor_bloc/wall_sensor_event.dart';
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/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';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/title_medium.dart';
import 'package:syncrow_app/generated/assets.dart';
import 'package:syncrow_app/utils/context_extension.dart';
import 'package:syncrow_app/utils/helpers/misc_string_helpers.dart';
import 'package:syncrow_app/utils/helpers/snack_bar.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
import 'package:syncrow_app/utils/resource_manager/constants.dart';
import 'package:syncrow_app/utils/resource_manager/font_manager.dart';
part "parameters_list.dart";
part "presence_indicator.dart";
part "../ceiling_sensor/parameter_control_dialog.dart";
class WallMountedInterface extends StatelessWidget {
const WallMountedInterface({super.key, required this.deviceModel});
final DeviceModel deviceModel;
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => WallSensorBloc(deviceId: deviceModel.uuid ?? '')..add(InitialEvent()),
child: BlocBuilder<WallSensorBloc, WallSensorState>(builder: (context, state) {
WallSensorModel wallSensorModel = WallSensorModel(
presenceState: 'none',
farDetection: 0,
presenceTime: 0,
motionSensitivity: 0,
motionlessSensitivity: 0,
currentDistance: 0,
illuminance: 0,
indicator: false);
if (state is UpdateState) {
wallSensorModel = state.wallSensorModel;
} else if (state is LoadingNewSate) {
wallSensorModel = state.wallSensorModel;
}
return AnnotatedRegion(
value: SystemUiOverlayStyle(
statusBarColor: ColorsManager.primaryColor.withOpacity(0.5),
statusBarIconBrightness: Brightness.light,
),
child: SafeArea(
child: Scaffold(
backgroundColor: ColorsManager.backgroundColor,
extendBodyBehindAppBar: true,
extendBody: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
centerTitle: true,
title: BodyLarge(
text: deviceModel.name ?? "",
fontColor: ColorsManager.primaryColor,
fontWeight: FontsManager.bold,
),
),
body: Container(
width: MediaQuery.sizeOf(context).width,
height: MediaQuery.sizeOf(context).height,
padding: const EdgeInsets.all(Constants.defaultPadding),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage(
Assets.assetsImagesBackground,
),
fit: BoxFit.cover,
opacity: 0.4,
),
),
child: state is LoadingInitialState
? const Center(
child: RefreshProgressIndicator(),
)
: Column(
children: [
PresenceIndicator(
state: wallSensorModel.presenceState,
),
ParametersList(
wallSensor: deviceModel,
presenceSensorsModel: wallSensorModel,
),
],
),
),
),
),
);
}),
);
}
}