mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-07-15 01:35:23 +00:00
garage Alarm
This commit is contained in:
@ -34,11 +34,14 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
||||
on<ToggleDoorEvent>(openCloseGarageDoor);
|
||||
on<GetCounterEvent>(_getCounterValue);
|
||||
on<SetCounterValue>(_setCounterValue);
|
||||
on<SetTimeOutValue>(_setTimeOutAlarm);
|
||||
on<TickTimer>(_onTickTimer);
|
||||
on<InitialWizardEvent>(_fetchWizardStatus);
|
||||
on<GroupAllOnEvent>(_groupAllOn);
|
||||
on<GroupAllOffEvent>(_groupAllOff);
|
||||
on<ChangeFirstWizardSwitchStatusEvent>(_changeFirstWizardSwitch);
|
||||
on<ToggleAlarmEvent>(_toggleAlarmEvent);
|
||||
//_toggleAlarmEvent
|
||||
}
|
||||
void _onClose(OnClose event, Emitter<GarageDoorSensorState> emit) {
|
||||
_timer?.cancel();
|
||||
@ -84,6 +87,32 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
||||
}
|
||||
}
|
||||
|
||||
void _toggleAlarmEvent(
|
||||
ToggleAlarmEvent event,
|
||||
Emitter<GarageDoorSensorState> emit,
|
||||
) async {
|
||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||
|
||||
try {
|
||||
deviceStatus.doorState1 = event.isEnabled;
|
||||
|
||||
emit(UpdateState(garageSensor: deviceStatus));
|
||||
|
||||
await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: GDId,
|
||||
code: 'door_state_1',
|
||||
value: event.isEnabled,
|
||||
),
|
||||
GDId,
|
||||
);
|
||||
|
||||
emit(UpdateState(garageSensor: deviceStatus));
|
||||
} catch (e) {
|
||||
emit(GarageDoorFailedState(errorMessage: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void _toggleClosingReminder(ToggleClosingReminderEvent event,
|
||||
Emitter<GarageDoorSensorState> emit) async {
|
||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||
@ -563,4 +592,29 @@ class GarageDoorBloc extends Bloc<GarageDoorEvent, GarageDoorSensorState> {
|
||||
add(InitialEvent(groupScreen: oneGangGroup));
|
||||
}
|
||||
}
|
||||
|
||||
void _setTimeOutAlarm(
|
||||
SetTimeOutValue event, Emitter<GarageDoorSensorState> emit) async {
|
||||
emit(LoadingNewSate(doorSensor: deviceStatus));
|
||||
int seconds = 0;
|
||||
try {
|
||||
seconds = event.duration.inSeconds;
|
||||
final response = await DevicesAPI.controlDevice(
|
||||
DeviceControlModel(
|
||||
deviceId: GDId, code: 'countdown_alarm', value: seconds),
|
||||
GDId);
|
||||
|
||||
if (response['success'] ?? false) {
|
||||
deviceStatus.countdownAlarm = seconds;
|
||||
CustomSnackBar.displaySnackBar('Save Successfully');
|
||||
add(GetScheduleEvent());
|
||||
} else {
|
||||
emit(const GarageDoorFailedState(errorMessage: 'Something went wrong'));
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
emit(GarageDoorFailedState(errorMessage: e.toString()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,13 +39,13 @@ class GetCounterEvent extends GarageDoorEvent {
|
||||
List<Object> get props => [deviceCode];
|
||||
}
|
||||
|
||||
class ToggleLowBatteryEvent extends GarageDoorEvent {
|
||||
final bool isLowBatteryEnabled;
|
||||
class ToggleAlarmEvent extends GarageDoorEvent {
|
||||
final String isEnabled;
|
||||
|
||||
const ToggleLowBatteryEvent(this.isLowBatteryEnabled);
|
||||
const ToggleAlarmEvent(this.isEnabled);
|
||||
|
||||
@override
|
||||
List<Object> get props => [isLowBatteryEnabled];
|
||||
List<Object> get props => [isEnabled];
|
||||
}
|
||||
|
||||
class ToggleClosingReminderEvent extends GarageDoorEvent {
|
||||
@ -74,6 +74,14 @@ class SetCounterValue extends GarageDoorEvent {
|
||||
List<Object> get props => [duration, deviceCode];
|
||||
}
|
||||
|
||||
class SetTimeOutValue extends GarageDoorEvent {
|
||||
final Duration duration;
|
||||
final String deviceCode;
|
||||
const SetTimeOutValue({required this.duration, required this.deviceCode});
|
||||
@override
|
||||
List<Object> get props => [duration, deviceCode];
|
||||
}
|
||||
|
||||
class StartTimer extends GarageDoorEvent {
|
||||
final int duration;
|
||||
|
||||
|
@ -21,7 +21,8 @@ class WallSensorBloc extends Bloc<WallSensorEvent, WallSensorState> {
|
||||
}
|
||||
|
||||
void _fetchCeilingSensorStatus(
|
||||
InitialEvent event, Emitter<WallSensorState> emit) async {
|
||||
InitialEvent event,
|
||||
Emitter<WallSensorState> emit) async {
|
||||
emit(LoadingInitialState());
|
||||
try {
|
||||
var response = await DevicesAPI.getDeviceStatus(deviceId);
|
||||
|
@ -18,7 +18,8 @@ class PreferencesPage extends StatelessWidget {
|
||||
return DefaultScaffold(
|
||||
title: 'Preferences',
|
||||
child: BlocProvider(
|
||||
create: (context) => GarageDoorBloc(GDId: GDId)..add(const GarageDoorInitial()),
|
||||
create: (context) =>
|
||||
GarageDoorBloc(GDId: GDId)..add(const GarageDoorInitial()),
|
||||
child: BlocBuilder<GarageDoorBloc, GarageDoorSensorState>(
|
||||
builder: (context, state) {
|
||||
final garageDoorBloc = BlocProvider.of<GarageDoorBloc>(context);
|
||||
@ -26,7 +27,9 @@ class PreferencesPage extends StatelessWidget {
|
||||
return state is GarageDoorLoadingState
|
||||
? const Center(
|
||||
child: DefaultContainer(
|
||||
width: 50, height: 50, child: CircularProgressIndicator()),
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: CircularProgressIndicator()),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
@ -49,14 +52,42 @@ class PreferencesPage extends StatelessWidget {
|
||||
height: 50,
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const BodyMedium(
|
||||
text: 'Alarm when door is open',
|
||||
fontWeight: FontWeight.normal,
|
||||
leading: InkWell(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return TimeoutDialog(
|
||||
duration: Duration(
|
||||
seconds: garageDoorBloc
|
||||
.deviceStatus
|
||||
.countdownAlarm),
|
||||
title: 'Timeout Alarm',
|
||||
cancelTab: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
confirmTab: (selectedSecond) {
|
||||
garageDoorBloc.add(
|
||||
SetTimeOutValue(
|
||||
deviceCode:
|
||||
'countdown_alarm',
|
||||
duration:
|
||||
selectedSecond));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
);
|
||||
});
|
||||
},
|
||||
child: const BodyMedium(
|
||||
text: 'Alarm when door is open',
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
),
|
||||
trailing: Container(
|
||||
width: 100,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
height: 30,
|
||||
@ -64,18 +95,25 @@ class PreferencesPage extends StatelessWidget {
|
||||
color: ColorsManager.graysColor,
|
||||
),
|
||||
Transform.scale(
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: garageDoorBloc.lowBattery,
|
||||
onChanged: (value) {
|
||||
// context
|
||||
// .read<GarageDoorBloc>()
|
||||
// .add(
|
||||
// ToggleLowBatteryEvent(
|
||||
// value));
|
||||
},
|
||||
applyTheme: true,
|
||||
)),
|
||||
scale: .8,
|
||||
child: CupertinoSwitch(
|
||||
value: garageDoorBloc.deviceStatus
|
||||
.doorState1 ==
|
||||
'unclosed_time',
|
||||
onChanged: (value) {
|
||||
context
|
||||
.read<GarageDoorBloc>()
|
||||
.add(
|
||||
ToggleAlarmEvent(
|
||||
value
|
||||
? 'unclosed_time'
|
||||
: 'close_time_alarm',
|
||||
),
|
||||
);
|
||||
},
|
||||
applyTheme: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
@ -103,12 +141,15 @@ class PreferencesPage extends StatelessWidget {
|
||||
builder: (context) {
|
||||
return SecondDialog(
|
||||
label2: 'Close',
|
||||
initialSelectedLabel: garageDoorBloc.secondSelected.toString(),
|
||||
initialSelectedLabel: garageDoorBloc
|
||||
.secondSelected
|
||||
.toString(),
|
||||
cancelTab: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
confirmTab: (v) {
|
||||
garageDoorBloc.add(SelectSecondsEvent(seconds: v));
|
||||
garageDoorBloc
|
||||
.add(SelectSecondsEvent(seconds: v));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
title: 'Control',
|
||||
@ -129,8 +170,10 @@ class PreferencesPage extends StatelessWidget {
|
||||
height: 90,
|
||||
width: 120,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BodyMedium(
|
||||
fontColor: ColorsManager.textGray,
|
||||
@ -156,6 +199,7 @@ class PreferencesPage extends StatelessWidget {
|
||||
));
|
||||
}
|
||||
}
|
||||
//Timeout
|
||||
|
||||
class SecondDialog extends StatefulWidget {
|
||||
final String label1;
|
||||
@ -183,15 +227,12 @@ class SecondDialog extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _SecondDialogState extends State<SecondDialog> {
|
||||
// late String _selectedOption;
|
||||
late int selectedSecond;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Parse the initialSelectedLabel as an integer. Default to 10 if invalid or not provided.
|
||||
selectedSecond = int.tryParse(widget.initialSelectedLabel ?? '10') ?? 10;
|
||||
// _selectedOption = widget.initialSelectedLabel ?? '';
|
||||
}
|
||||
|
||||
@override
|
||||
@ -229,7 +270,6 @@ class _SecondDialogState extends State<SecondDialog> {
|
||||
child: CupertinoPicker(
|
||||
itemExtent: 40.0,
|
||||
scrollController: FixedExtentScrollController(
|
||||
// Set the initial position based on selectedSecond
|
||||
initialItem: selectedSecond - 10,
|
||||
),
|
||||
onSelectedItemChanged: (int index) {
|
||||
@ -242,7 +282,9 @@ class _SecondDialogState extends State<SecondDialog> {
|
||||
child: BodyLarge(
|
||||
text: (index + 10).toString().padLeft(2, '0'),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w400, fontSize: 30, color: Colors.blue),
|
||||
fontWeight: FontWeight.w400,
|
||||
fontSize: 30,
|
||||
color: Colors.blue),
|
||||
),
|
||||
);
|
||||
}),
|
||||
@ -326,3 +368,153 @@ class _SecondDialogState extends State<SecondDialog> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TimeoutDialog extends StatefulWidget {
|
||||
final String title;
|
||||
final Function(String)? onTapLabel1;
|
||||
final Function()? cancelTab;
|
||||
final Function(Duration timeSelected)? confirmTab;
|
||||
final Duration? duration;
|
||||
|
||||
TimeoutDialog({
|
||||
required this.title,
|
||||
this.onTapLabel1,
|
||||
required this.cancelTab,
|
||||
required this.confirmTab,
|
||||
this.duration,
|
||||
});
|
||||
|
||||
@override
|
||||
_TimeoutDialogState createState() => _TimeoutDialogState();
|
||||
}
|
||||
|
||||
class _TimeoutDialogState extends State<TimeoutDialog> {
|
||||
late int selectedSecond;
|
||||
Duration duration = Duration.zero;
|
||||
int countNum = 0;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
duration = widget.duration!;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
BodyLarge(
|
||||
text: widget.title,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontColor: ColorsManager.primaryColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(left: 15, right: 15),
|
||||
child: Divider(
|
||||
color: ColorsManager.textGray,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 15, right: 15, bottom: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
Center(
|
||||
child: Container(
|
||||
height: 150,
|
||||
width: MediaQuery.of(context).size.width * 1,
|
||||
child: CupertinoTimerPicker(
|
||||
initialTimerDuration: duration,
|
||||
mode: CupertinoTimerPickerMode.hm,
|
||||
onTimerDurationChanged: (Duration newDuration) {
|
||||
duration = newDuration;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
right: BorderSide(
|
||||
color: ColorsManager.textGray,
|
||||
width: 0.5,
|
||||
),
|
||||
top: BorderSide(
|
||||
color: ColorsManager.textGray,
|
||||
width: 1.0,
|
||||
),
|
||||
)),
|
||||
child: SizedBox(
|
||||
child: InkWell(
|
||||
onTap: widget.cancelTab,
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Cancel',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.textGray,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
decoration: const BoxDecoration(
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
color: ColorsManager.textGray,
|
||||
width: 0.5,
|
||||
),
|
||||
top: BorderSide(
|
||||
color: ColorsManager.textGray,
|
||||
width: 1.0,
|
||||
),
|
||||
)),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
widget.confirmTab?.call(duration);
|
||||
},
|
||||
child: const Padding(
|
||||
padding: EdgeInsets.all(15),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Confirm',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.primaryColor,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400),
|
||||
),
|
||||
),
|
||||
)),
|
||||
))
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String _formatDuration(int seconds) {
|
||||
final hours = (seconds ~/ 3600).toString().padLeft(2, '0');
|
||||
final minutes = ((seconds % 3600) ~/ 60).toString().padLeft(2, '0');
|
||||
final secs = (seconds % 60).toString().padLeft(2, '0');
|
||||
return '$hours:$minutes:$secs';
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ class DevicesAPI {
|
||||
body: controlModel.toJson(),
|
||||
showServerMessage: true,
|
||||
expectedResponseModel: (json) {
|
||||
print(json);
|
||||
return json;
|
||||
},
|
||||
);
|
||||
|
@ -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.3+26
|
||||
version: 1.0.4+26
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.6 <4.0.0"
|
||||
|
Reference in New Issue
Block a user