door sensor

This commit is contained in:
mohammad
2024-09-22 15:32:47 +03:00
parent 7279215cdc
commit 58e13da887
18 changed files with 1301 additions and 111 deletions

View File

@ -0,0 +1,220 @@
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
import 'package:syncrow_app/features/devices/model/device_control_model.dart';
import 'package:syncrow_app/features/devices/model/door_sensor_model.dart';
import 'package:syncrow_app/features/devices/model/report_model.dart';
import 'package:syncrow_app/features/devices/model/status_model.dart';
import 'package:syncrow_app/services/api/devices_api.dart';
class DoorSensorBloc extends Bloc<DoorSensorEvent, DoorSensorState> {
final String DSId;
final String switchCode;
DoorSensorBloc({required this.DSId, required this.switchCode})
: super(const DoorSensorState()) {
on<DoorSensorInitial>(_fetchWaterHeaterStatus);
on<ReportLogsInitial>(fetchLogsForLastMonth);
on<DoorSensorSwitch>(_changeFirstSwitch);
on<ToggleLowBatteryEvent>(_toggleLowBattery);
on<ToggleClosingReminderEvent>(_toggleClosingReminder);
on<ToggleDoorAlarmEvent>(_toggleDoorAlarm);
}
Timer? _timer;
bool lowBattery = false;
bool closingReminder = false;
bool doorAlarm = false;
DoorSensorModel deviceStatus =
DoorSensorModel(doorContactState: false, batteryPercentage: 0);
void _fetchWaterHeaterStatus(
DoorSensorInitial event, Emitter<DoorSensorState> emit) async {
emit(DoorSensorLoadingState());
try {
var response = await DevicesAPI.getDeviceStatus(DSId);
List<StatusModel> statusModelList = [];
for (var status in response['status']) {
statusModelList.add(StatusModel.fromJson(status));
}
deviceStatus = DoorSensorModel.fromJson(
statusModelList,
);
emit(UpdateState(doorSensor: deviceStatus));
Future.delayed(const Duration(milliseconds: 500));
// _listenToChanges();
} catch (e) {
emit(DoorSensorFailedState(errorMessage: e.toString()));
return;
}
}
void _changeFirstSwitch(
DoorSensorSwitch event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
deviceStatus.doorContactState = !event.switchD;
emit(UpdateState(doorSensor: deviceStatus));
final response = await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: DSId,
code: 'doorcontact_state',
value: deviceStatus.doorContactState),
DSId);
if (!response['success']) {
// add(InitialEvent(groupScreen: oneGangGroup));
}
} catch (_) {
emit(DoorSensorFailedState(errorMessage: _.toString()));
}
}
// Toggle functions for each switch
void _toggleLowBattery(
ToggleLowBatteryEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
lowBattery = event.isLowBatteryEnabled;
emit(UpdateState(doorSensor: deviceStatus));
// API call to update the state, if necessary
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: DSId,
code: 'low_battery',
value: lowBattery,
),
DSId,
);
} catch (e) {
emit(DoorSensorFailedState(errorMessage: e.toString()));
}
}
void _toggleClosingReminder(
ToggleClosingReminderEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
closingReminder = event.isClosingReminderEnabled;
emit(UpdateState(doorSensor: deviceStatus));
// API call to update the state, if necessary
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: DSId,
code: 'closing_reminder',
value: closingReminder,
),
DSId,
);
} catch (e) {
emit(DoorSensorFailedState(errorMessage: e.toString()));
}
}
void _toggleDoorAlarm(
ToggleDoorAlarmEvent event, Emitter<DoorSensorState> emit) async {
emit(LoadingNewSate(doorSensor: deviceStatus));
try {
doorAlarm = event.isDoorAlarmEnabled;
emit(UpdateState(doorSensor: deviceStatus));
// API call to update the state, if necessary
await DevicesAPI.controlDevice(
DeviceControlModel(
deviceId: DSId,
code: 'door_alarm',
value: doorAlarm,
),
DSId,
);
} catch (e) {
emit(DoorSensorFailedState(errorMessage: e.toString()));
}
}
final List<RecordGroup> recordGroups = [
RecordGroup(
date: DateTime(2024, 8, 31),
records: [
Record(status: 'Opened', time: '15:10:25', isOpen: false),
Record(status: 'Closed', time: '12:24:45', isOpen: false),
Record(status: 'Opened', time: '12:20:05', isOpen: true),
],
),
RecordGroup(
date: DateTime(2024, 8, 30),
records: [
Record(status: 'Opened', time: '14:15:30', isOpen: true),
Record(status: 'Closed', time: '10:22:45', isOpen: false),
],
),
RecordGroup(
date: DateTime(2024, 8, 29),
records: [
Record(status: 'Opened', time: '13:45:00', isOpen: true),
Record(status: 'Closed', time: '11:30:15', isOpen: false),
Record(status: 'Opened', time: '09:20:10', isOpen: true),
],
),
];
Future<void> fetchLogsForLastMonth(
ReportLogsInitial event, Emitter<DoorSensorState> emit) async {
// Get the current date and time
DateTime now = DateTime.now();
// Calculate the date one month ago
DateTime lastMonth = DateTime(now.year, now.month - 1, now.day);
// Convert the date to milliseconds since epoch (Unix timestamp in milliseconds)
int startTime = lastMonth.millisecondsSinceEpoch;
int endTime = now.millisecondsSinceEpoch;
try {
var response = await DevicesAPI.getReportLogs(
startTime: startTime.toString(), // Convert to String if the API expects it
endTime: endTime.toString(), // Convert to String if the API expects it
deviceUuid: DSId,
code: 'doorcontact_state',
);
// Process response here
print(response);
} on DioException catch (e) {
final errorData = e.response!.data;
String errorMessage = errorData['message'];
// Handle error
print('Error fetching logs: ${errorMessage}');
}
}
_listenToChanges() {
try {
DatabaseReference ref =
FirebaseDatabase.instance.ref('device-status/$DSId');
Stream<DatabaseEvent> stream = ref.onValue;
stream.listen((DatabaseEvent event) async {
if (_timer != null) {
await Future.delayed(const Duration(seconds: 2));
}
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 = DoorSensorModel.fromJson(statusList);
if (!isClosed) {
add(
DoorSensorSwitch(switchD: deviceStatus.doorContactState),
);
}
});
} catch (_) {}
}
}

View File

@ -0,0 +1,102 @@
import 'package:equatable/equatable.dart';
abstract class DoorSensorEvent extends Equatable {
const DoorSensorEvent();
@override
List<Object> get props => [];
}
class DoorSensorLoading extends DoorSensorEvent {}
class DoorSensorSwitch extends DoorSensorEvent {
final bool switchD;
final String deviceId;
final String productId;
const DoorSensorSwitch({required this.switchD, this.deviceId = '', this.productId = ''});
@override
List<Object> get props => [switchD, deviceId, productId];
}
class DoorSensorUpdated extends DoorSensorEvent {}
class DoorSensorInitial extends DoorSensorEvent {
const DoorSensorInitial();
}
class ReportLogsInitial extends DoorSensorEvent {
const ReportLogsInitial();
}
class DoorSensorChangeStatus extends DoorSensorEvent {}
class GetCounterEvent extends DoorSensorEvent {
final String deviceCode;
const GetCounterEvent({required this.deviceCode});
@override
List<Object> get props => [deviceCode];
}
class ToggleLowBatteryEvent extends DoorSensorEvent {
final bool isLowBatteryEnabled;
const ToggleLowBatteryEvent(this.isLowBatteryEnabled);
@override
List<Object> get props => [isLowBatteryEnabled];
}
class ToggleClosingReminderEvent extends DoorSensorEvent {
final bool isClosingReminderEnabled;
const ToggleClosingReminderEvent(this.isClosingReminderEnabled);
@override
List<Object> get props => [isClosingReminderEnabled];
}
class ToggleDoorAlarmEvent extends DoorSensorEvent {
final bool isDoorAlarmEnabled;
const ToggleDoorAlarmEvent(this.isDoorAlarmEnabled);
@override
List<Object> get props => [isDoorAlarmEnabled];
}
class SetCounterValue extends DoorSensorEvent {
final Duration duration;
final String deviceCode;
const SetCounterValue({required this.duration, required this.deviceCode});
@override
List<Object> get props => [duration, deviceCode];
}
class StartTimer extends DoorSensorEvent {
final int duration;
const StartTimer(this.duration);
@override
List<Object> get props => [duration];
}
class TickTimer extends DoorSensorEvent {
final int remainingTime;
const TickTimer(this.remainingTime);
@override
List<Object> get props => [remainingTime];
}
class StopTimer extends DoorSensorEvent {}
class OnClose extends DoorSensorEvent {}

View File

@ -0,0 +1,128 @@
import 'package:equatable/equatable.dart';
import 'package:syncrow_app/features/devices/model/door_sensor_model.dart';
class DoorSensorState extends Equatable {
const DoorSensorState();
@override
List<Object> get props => [];
}
class DoorSensorInitialState extends DoorSensorState {}
class DoorSensorLoadingState extends DoorSensorState {}
class DoorSensorFailedState extends DoorSensorState {
final String errorMessage;
const DoorSensorFailedState({required this.errorMessage});
@override
List<Object> get props => [errorMessage];
}
class UpdateState extends DoorSensorState {
final DoorSensorModel doorSensor;
const UpdateState({required this.doorSensor});
@override
List<Object> get props => [doorSensor];
}
class LoadingNewSate extends DoorSensorState {
final DoorSensorModel doorSensor;
const LoadingNewSate({required this.doorSensor});
@override
List<Object> get props => [doorSensor];
}
// class WHModifyingState extends DoorSensorState {
// final WHModel whStatusModel;
// const WHModifyingState({required this.whStatusModel});
//
// @override
// List<Object> get props => [whStatusModel];
// }
//
// class GetWHStatusState extends DoorSensorState {
// final WHModel whStatusModel;
// const GetWHStatusState({required this.whStatusModel});
//
// @override
// List<Object> get props => [whStatusModel];
// }
//
//
// class WHFailedState extends WaterHeaterState {
// final String errorMessage;
//
// const WHFailedState({required this.errorMessage});
//
// @override
// List<Object> get props => [errorMessage];
// }
// class LoadingNewSate extends WaterHeaterState {
// final WHModel whModel;
// const LoadingNewSate({required this.whModel});
//
// @override
// List<Object> get props => [whModel];
// }
// class TimerRunComplete extends WaterHeaterState {}
// class UpdateTimerState extends WaterHeaterState {
// final int seconds;
// const UpdateTimerState({required this.seconds});
//
// @override
// List<Object> get props => [seconds];
// }
//
// class TimerRunInProgress extends WaterHeaterState {
// final int remainingTime;
//
// const TimerRunInProgress(this.remainingTime);
//
// @override
// List<Object> get props => [remainingTime];
// }
//
// class SaveSchedule extends WaterHeaterState {}
// class ChangeTimeState extends WaterHeaterState {}
// class UpdateCreateScheduleState extends WaterHeaterState {
// final bool createSchedule;
// UpdateCreateScheduleState(this.createSchedule);
// }
// class IsToggleState extends WaterHeaterState {
// final bool? onOff;
// const IsToggleState({this.onOff});
// }
//
//
// class UpdateState extends WaterHeaterState {
// final WHModel whModel;
// const UpdateState({required this.whModel});
//
// @override
// List<Object> get props => [WHModel];
// }
//
// class ChangeSwitchStatusEvent extends WaterHeaterState {
// final bool value;
// final String deviceId;
// const ChangeSwitchStatusEvent({required this.value, this.deviceId = ''});
// @override
// List<Object> get props => [value, deviceId];
// }
//
// class ChangeSlidingSegmentState extends WaterHeaterState {
// final int value;
//
// const ChangeSlidingSegmentState({required this.value});
//
// @override
// List<Object> get props => [value];
// }

View File

@ -0,0 +1,33 @@
import 'package:syncrow_app/features/devices/model/status_model.dart';
class DoorSensorModel {
bool doorContactState;
int batteryPercentage;
DoorSensorModel(
{required this.doorContactState,
required this.batteryPercentage,
});
factory DoorSensorModel.fromJson(List<StatusModel> jsonList) {
late bool _doorContactState;
late int _batteryPercentage;
for (int i = 0; i < jsonList.length; i++) {
if (jsonList[i].code == 'doorcontact_state') {
_doorContactState = jsonList[i].value ?? false;
} else if (jsonList[i].code == 'battery_percentage') {
_batteryPercentage = jsonList[i].value ?? 0;
}
}
return DoorSensorModel(
doorContactState: _doorContactState,
batteryPercentage: _batteryPercentage,
);
}
}

View File

@ -0,0 +1,23 @@
// Record model
class Record {
final String status;
final String time;
final bool isOpen;
Record({
required this.status,
required this.time,
required this.isOpen,
});
}
// RecordGroup model to group records by date
class RecordGroup {
final DateTime date;
final List<Record> records;
RecordGroup({
required this.date,
required this.records,
});
}

View File

@ -0,0 +1,123 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
import 'package:syncrow_app/features/devices/model/door_sensor_model.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_large.dart';
import 'package:syncrow_app/utils/resource_manager/color_manager.dart';
class NotificationSettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Notification Settings',
child: BlocProvider(
create: (context) => DoorSensorBloc(switchCode: 'switch_1', DSId: '')
..add(const DoorSensorInitial()),
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
builder: (context, state) {
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
DoorSensorModel model = DoorSensorModel(
batteryPercentage: 0, doorContactState: false);
if (state is LoadingNewSate) {
model = state.doorSensor;
} else if (state is UpdateState) {
model = state.doorSensor;
}
return state is DoorSensorLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: Column(
children: [
DefaultContainer(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 50,
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyLarge(
text: 'Low Battery',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: doorSensorBloc.lowBattery,
onChanged: (value) {
context.read<DoorSensorBloc>().add(
ToggleLowBatteryEvent(value));
},
applyTheme: true,
)),
),
),
const Divider(
color: ColorsManager.graysColor,
),
SizedBox(
height: 50,
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyLarge(
text: 'Closing Reminder',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: doorSensorBloc.closingReminder,
onChanged: (value) {
context.read<DoorSensorBloc>().add(
ToggleClosingReminderEvent(
value));
},
applyTheme: true,
)),
),
),
const Divider(
color: ColorsManager.graysColor,
),
SizedBox(
height: 50,
child: ListTile(
contentPadding: EdgeInsets.zero,
leading: const BodyLarge(
text: 'Door Alarm',
fontWeight: FontWeight.normal,
),
trailing: Transform.scale(
scale: .8,
child: CupertinoSwitch(
value: doorSensorBloc.closingReminder,
onChanged: (value) {
context
.read<DoorSensorBloc>()
.add(ToggleDoorAlarmEvent(value));
},
applyTheme: true,
)),
),
),
],
),
),
],
);
},
),
));
}
}

View File

@ -0,0 +1,77 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
class DoorRecordsScreen extends StatelessWidget {
final String DSId;
const DoorRecordsScreen({super.key,required this.DSId});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Records',
child: BlocProvider(
create: (context) =>
DoorSensorBloc(switchCode: 'switch_1', DSId:DSId )
..add(const ReportLogsInitial()),
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
builder: (context, state) {
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
return SizedBox(
child: ListView.builder(
itemCount: doorSensorBloc.recordGroups.length,
itemBuilder: (context, index) {
final recordGroup = doorSensorBloc.recordGroups[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Date header
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(
DateFormat('EEEE, dd/MM/yyyy')
.format(recordGroup.date),
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
),
// Display each record for the date
DefaultContainer(
child: Column(
children: recordGroup.records.map((record) {
return ListTile(
leading: Icon(
record.isOpen
? Icons.radio_button_checked
: Icons.radio_button_unchecked,
color:
record.isOpen ? Colors.blue : Colors.grey,
),
title: Text(
record.status,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
subtitle: Text(record.time),
);
}).toList(),
),
),
],
);
},
),
);
})));
}
}

View File

@ -0,0 +1,207 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_bloc.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_event.dart';
import 'package:syncrow_app/features/devices/bloc/door_sensor_bloc/door_sensor_state.dart';
import 'package:syncrow_app/features/devices/model/device_model.dart';
import 'package:syncrow_app/features/devices/model/door_sensor_model.dart';
import 'package:syncrow_app/features/devices/view/widgets/door_sensor/door_notification_settings.dart';
import 'package:syncrow_app/features/devices/view/widgets/door_sensor/door_records_screen.dart';
import 'package:syncrow_app/features/shared_widgets/battery_bar.dart';
import 'package:syncrow_app/features/shared_widgets/default_container.dart';
import 'package:syncrow_app/features/shared_widgets/default_scaffold.dart';
import 'package:syncrow_app/features/shared_widgets/text_widgets/body_small.dart';
import 'package:syncrow_app/generated/assets.dart';
class DoorSensorScreen extends StatelessWidget {
final DeviceModel? device;
const DoorSensorScreen({super.key, this.device});
@override
Widget build(BuildContext context) {
return DefaultScaffold(
title: 'Door Sensor',
child: BlocProvider(
create: (context) =>
DoorSensorBloc(switchCode: 'switch_1', DSId: device?.uuid ?? '')
..add(const DoorSensorInitial()),
child: BlocBuilder<DoorSensorBloc, DoorSensorState>(
builder: (context, state) {
final doorSensorBloc = BlocProvider.of<DoorSensorBloc>(context);
DoorSensorModel model =
DoorSensorModel(batteryPercentage: 0, doorContactState: false);
if (state is LoadingNewSate) {
model = state.doorSensor;
} else if (state is UpdateState) {
model = state.doorSensor;
}
return state is DoorSensorLoadingState
? const Center(
child: DefaultContainer(
width: 50,
height: 50,
child: CircularProgressIndicator()),
)
: RefreshIndicator(
onRefresh: () async {
doorSensorBloc.add(const DoorSensorInitial());
},
child: Center(
child: ListView(
shrinkWrap: true,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BatteryBar(
batteryPercentage: model.batteryPercentage,
),
InkWell(
overlayColor:
WidgetStateProperty.all(Colors.transparent),
onTap: () {
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
// color: Colors.white.withOpacity(0.1),
borderRadius:
BorderRadius.circular(890),
boxShadow: [
BoxShadow(
color:
Colors.white.withOpacity(0.1),
blurRadius: 24,
offset: const Offset(-5, -5),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color:
Colors.black.withOpacity(0.11),
blurRadius: 25,
offset: const Offset(5, 5),
blurStyle: BlurStyle.outer,
),
BoxShadow(
color:
Colors.black.withOpacity(0.13),
blurRadius: 30,
offset: const Offset(5, 5),
blurStyle: BlurStyle.inner,
),
],
),
child: SvgPicture.asset(
model.doorContactState
? Assets.doorOpen
: Assets.doorClose,
fit: BoxFit.fill,
),
),
],
),
),
const SizedBox(height: 80),
],
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.13,
child: Row(
children: [
Expanded(
child: DefaultContainer(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
DoorRecordsScreen(
DSId: device!.uuid!)),
);
},
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46, maxWidth: 50),
child: SvgPicture.asset(
Assets.doorRecordsIcon),
),
const SizedBox(
height: 15,
),
const Flexible(
child: FittedBox(
child: BodySmall(
text: 'Records',
// doorLockButtons.keys.elementAt(index),
textAlign: TextAlign.center,
),
),
),
],
),
),
),
const SizedBox(
width: 10,
),
Expanded(
child: DefaultContainer(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
NotificationSettingsPage()),
);
},
child: Column(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
ConstrainedBox(
constraints: const BoxConstraints(
maxHeight: 46, maxWidth: 50),
child: SvgPicture.asset(
Assets.doorNotificationSetting),
),
const SizedBox(
height: 15,
),
const Flexible(
child: FittedBox(
child: BodySmall(
text: 'Notification Settings',
// doorLockButtons.keys.elementAt(index),
textAlign: TextAlign.center,
),
),
),
],
),
),
),
],
),
)
],
),
),
);
},
),
),
);
}
}

View File

@ -9,10 +9,10 @@ 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/curtains/curtain_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/door_sensor/door_sensor_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/gateway/gateway_view.dart';
import 'package:syncrow_app/features/devices/view/widgets/lights/light_interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_Interface.dart';
import 'package:syncrow_app/features/devices/view/widgets/one_gang/one_gang_screen.dart';
import 'package:syncrow_app/features/devices/view/widgets/two_gang/two_gang_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';
@ -31,7 +31,6 @@ class RoomPageSwitch extends StatelessWidget {
});
final DeviceModel device;
@override
Widget build(BuildContext context) {
return GestureDetector(
@ -87,7 +86,8 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => ACsView(deviceModel: device)));
pageBuilder: (context, animation1, animation2) =>
ACsView(deviceModel: device)));
// navigateToInterface(ACsView(deviceModel: device), context);
break;
case DeviceType.WallSensor:
@ -110,8 +110,9 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
CurtainView(curtain: device,)));
pageBuilder: (context, animation1, animation2) => CurtainView(
curtain: device,
)));
break;
case DeviceType.Blind:
break;
@ -119,14 +120,16 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => DoorInterface(doorLock: device)));
pageBuilder: (context, animation1, animation2) =>
DoorInterface(doorLock: device)));
// navigateToInterface(DoorInterface(doorlock: device), context);
break;
case DeviceType.Gateway:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) => GateWayView(gatewayObj: device)));
pageBuilder: (context, animation1, animation2) =>
GateWayView(gatewayObj: device)));
break;
case DeviceType.LightBulb:
navigateToInterface(LightInterface(light: device), context);
@ -149,13 +152,18 @@ void showDeviceInterface(DeviceModel device, BuildContext context) {
pageBuilder: (context, animation1, animation2) =>
ThreeGangInterface(gangSwitch: device)));
case DeviceType.WH:
case DeviceType.WH:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
WaterHeaterPage(device: device)));
case DeviceType.DS:
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (context, animation1, animation2) =>
DoorSensorScreen(device: device)));
break;
default:
}

View File

@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
class BatteryBar extends StatelessWidget {
const BatteryBar({
required this.batteryPercentage,
super.key,
});
final int batteryPercentage;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(),
Transform.rotate(
angle: 1.5708, // 90 degrees in radians (π/2 or 1.5708)
child: Icon(
_getBatteryIcon(batteryPercentage),
color: _getBatteryColor(batteryPercentage),
size: 30,
),
),
],
);
}
IconData _getBatteryIcon(int batteryLevel) {
// if (batteryState == BatteryState.charging) {
// return Icons.battery_charging_full;
// } else
if (batteryLevel >= 80) {
return Icons.battery_full;
} else if (batteryLevel >= 60) {
return Icons.battery_4_bar;
} else if (batteryLevel >= 40) {
return Icons.battery_3_bar;
} else if (batteryLevel >= 20) {
return Icons.battery_2_bar;
} else {
return Icons.battery_alert;
}
}
Color _getBatteryColor(int batteryLevel) {
if (batteryLevel >= 80) {
return Colors.green;
} else if (batteryLevel >= 40) {
return Colors.yellowAccent;
} else {
return Colors.red;
}
}
}

View File

@ -735,7 +735,7 @@ class Assets {
//assets/icons/success-white.svg
//assets for success white image
static const String assetsSuccessWhite ="assets/icons/success-white.svg";
static const String assetsSuccessWhite = "assets/icons/success-white.svg";
/// Assets for assetsImagesAutomation
/// assets/images/automation.jpg
@ -1044,13 +1044,18 @@ class Assets {
static const String waterHeaterOn = "assets/icons/water_heater_on.svg";
static const String waterHeaterOff = "assets/icons/water_heater_off.svg";
static const String scheduleCelenderIcon = "assets/icons/schedule_celender_icon.svg";
static const String scheduleCirculateIcon = "assets/icons/schedule_circulate_icon.svg";
static const String scheduleInchingIcon = "assets/icons/schedule_Inching_icon.svg";
static const String scheduleCelenderIcon =
"assets/icons/schedule_celender_icon.svg";
static const String scheduleCirculateIcon =
"assets/icons/schedule_circulate_icon.svg";
static const String scheduleInchingIcon =
"assets/icons/schedule_Inching_icon.svg";
static const String scheduleTimeIcon = "assets/icons/schedule_time_icon.svg";
static const String waterHeaterIcon = "assets/icons/water_heater_icon.svg";
static const String doorOpen = "assets/icons/opened_door.svg";
static const String doorClose = "assets/icons/closed_door.svg";
static const String doorNotificationSetting =
"assets/icons/door_notification_setting_icon.svg";
static const String doorRecordsIcon = "assets/icons/door_records_icon.svg";
}

View File

@ -81,7 +81,8 @@ abstract class ApiEndpoints {
static const String controlGroup = '/group/control';
//GET
static const String groupBySpace = '/group/{unitUuid}';
static const String devicesByGroupName = '/group/{unitUuid}/devices/{groupName}';
static const String devicesByGroupName =
'/group/{unitUuid}/devices/{groupName}';
static const String groupByUuid = '/group/{groupUuid}';
//DELETE
@ -93,7 +94,8 @@ abstract class ApiEndpoints {
static const String addDeviceToRoom = '/device/room';
static const String addDeviceToGroup = '/device/group';
static const String controlDevice = '/device/{deviceUuid}/control';
static const String firmwareDevice = '/device/{deviceUuid}/firmware/{firmwareVersion}';
static const String firmwareDevice =
'/device/{deviceUuid}/firmware/{firmwareVersion}';
static const String getDevicesByUserId = '/device/user/{userId}';
static const String getDevicesByUnitId = '/device/unit/{unitUuid}';
static const String openDoorLock = '/door-lock/open/{doorLockUuid}';
@ -103,7 +105,8 @@ abstract class ApiEndpoints {
static const String deviceByUuid = '/device/{deviceUuid}';
static const String deviceFunctions = '/device/{deviceUuid}/functions';
static const String gatewayApi = '/device/gateway/{gatewayUuid}/devices';
static const String deviceFunctionsStatus = '/device/{deviceUuid}/functions/status';
static const String deviceFunctionsStatus =
'/device/{deviceUuid}/functions/status';
///Device Permission Module
//POST
@ -128,24 +131,29 @@ abstract class ApiEndpoints {
static const String getUnitAutomation = '/automation/{unitUuid}';
static const String getAutomationDetails = '/automation/details/{automationId}';
static const String getAutomationDetails =
'/automation/details/{automationId}';
/// PUT
static const String updateScene = '/scene/tap-to-run/{sceneId}';
static const String updateAutomation = '/automation/{automationId}';
static const String updateAutomationStatus = '/automation/status/{automationId}';
static const String updateAutomationStatus =
'/automation/status/{automationId}';
/// DELETE
static const String deleteScene = '/scene/tap-to-run/{unitUuid}/{sceneId}';
static const String deleteAutomation = '/automation/{unitUuid}/{automationId}';
static const String deleteAutomation =
'/automation/{unitUuid}/{automationId}';
//////////////////////Door Lock //////////////////////
//online
static const String addTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
static const String getTemporaryPassword = '/door-lock/temporary-password/online/{doorLockUuid}';
static const String addTemporaryPassword =
'/door-lock/temporary-password/online/{doorLockUuid}';
static const String getTemporaryPassword =
'/door-lock/temporary-password/online/{doorLockUuid}';
//one-time offline
static const String addOneTimeTemporaryPassword =
@ -176,11 +184,10 @@ abstract class ApiEndpoints {
static const String deleteTemporaryPassword =
'/door-lock/temporary-password/online/{doorLockUuid}/{passwordId}';
static const String saveSchedule = '/schedule/{deviceUuid}';
static const String getSchedule = '/schedule/{deviceUuid}?category={category}';
static const String getSchedule =
'/schedule/{deviceUuid}?category={category}';
static const String changeSchedule = '/schedule/enable/{deviceUuid}';
static const String deleteSchedule = '/schedule/{deviceUuid}/{scheduleId}';
static const String reportLogs = '/device/report-logs/{deviceUuid}?code={code}&startTime={startTime}&endTime={endTime}';
}

View File

@ -39,7 +39,6 @@ class DevicesAPI {
expectedResponseModel: (json) {
return json;
},
);
return response;
} catch (e) {
@ -72,7 +71,8 @@ class DevicesAPI {
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.deviceFunctionsStatus.replaceAll('{deviceUuid}', deviceId),
path: ApiEndpoints.deviceFunctionsStatus
.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -82,7 +82,9 @@ class DevicesAPI {
}
static Future<Map<String, dynamic>> renamePass(
{required String name, required String doorLockUuid, required String passwordId}) async {
{required String name,
required String doorLockUuid,
required String passwordId}) async {
final response = await _httpService.put(
path: ApiEndpoints.renamePassword
.replaceAll('{doorLockUuid}', doorLockUuid)
@ -107,7 +109,8 @@ class DevicesAPI {
return response;
}
static Future<List<DeviceModel>> getDeviceByGroupName(String unitId, String groupName) async {
static Future<List<DeviceModel>> getDeviceByGroupName(
String unitId, String groupName) async {
final response = await _httpService.get(
path: ApiEndpoints.devicesByGroupName
.replaceAll('{unitUuid}', unitId)
@ -146,7 +149,8 @@ class DevicesAPI {
return response;
}
static Future<List<DeviceModel>> getDevicesByGatewayId(String gatewayId) async {
static Future<List<DeviceModel>> getDevicesByGatewayId(
String gatewayId) async {
final response = await _httpService.get(
path: ApiEndpoints.gatewayApi.replaceAll('{gatewayUuid}', gatewayId),
showServerMessage: false,
@ -168,7 +172,8 @@ class DevicesAPI {
String deviceId,
) async {
final response = await _httpService.get(
path: ApiEndpoints.getTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.getTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -179,7 +184,8 @@ class DevicesAPI {
static Future getOneTimePasswords(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.getOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.getOneTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -190,7 +196,8 @@ class DevicesAPI {
static Future getTimeLimitPasswords(String deviceId) async {
final response = await _httpService.get(
path: ApiEndpoints.getMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.getMultipleTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -215,10 +222,12 @@ class DevicesAPI {
"invalidTime": invalidTime,
};
if (scheduleList != null) {
body["scheduleList"] = scheduleList.map((schedule) => schedule.toJson()).toList();
body["scheduleList"] =
scheduleList.map((schedule) => schedule.toJson()).toList();
}
final response = await _httpService.post(
path: ApiEndpoints.addTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.addTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
body: body,
showServerMessage: false,
expectedResponseModel: (json) => json,
@ -229,7 +238,8 @@ class DevicesAPI {
static Future generateOneTimePassword({deviceId}) async {
try {
final response = await _httpService.post(
path: ApiEndpoints.addOneTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.addOneTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -241,10 +251,12 @@ class DevicesAPI {
}
}
static Future generateMultiTimePassword({deviceId, effectiveTime, invalidTime}) async {
static Future generateMultiTimePassword(
{deviceId, effectiveTime, invalidTime}) async {
try {
final response = await _httpService.post(
path: ApiEndpoints.addMultipleTimeTemporaryPassword.replaceAll('{doorLockUuid}', deviceId),
path: ApiEndpoints.addMultipleTimeTemporaryPassword
.replaceAll('{doorLockUuid}', deviceId),
showServerMessage: true,
body: {"effectiveTime": effectiveTime, "invalidTime": invalidTime},
expectedResponseModel: (json) {
@ -277,21 +289,22 @@ class DevicesAPI {
required String time,
required String code,
required bool value,
required List<String> days,
required List<String> days,
}) async {
final response = await _httpService.post(
path: ApiEndpoints.saveSchedule.replaceAll('{deviceUuid}', deviceId),
showServerMessage: false,
body:
jsonEncode({
"category": category,
"time": time,
"function":{
"code": code,
"value":value,
body: jsonEncode(
{
"category": category,
"time": time,
"function": {
"code": code,
"value": value,
},
"days": days
},
"days": days
},),
),
expectedResponseModel: (json) {
return json;
},
@ -304,7 +317,9 @@ class DevicesAPI {
required String deviceId,
}) async {
final response = await _httpService.get(
path: ApiEndpoints.getSchedule.replaceAll('{deviceUuid}', deviceId).replaceAll('{category}', category),
path: ApiEndpoints.getSchedule
.replaceAll('{deviceUuid}', deviceId)
.replaceAll('{category}', category),
showServerMessage: false,
expectedResponseModel: (json) {
return json;
@ -320,10 +335,7 @@ class DevicesAPI {
}) async {
final response = await _httpService.put(
path: ApiEndpoints.changeSchedule.replaceAll('{deviceUuid}', deviceUuid),
body: {
"scheduleId": scheduleId,
"enable": enable
},
body: {"scheduleId": scheduleId, "enable": enable},
expectedResponseModel: (json) {
return json['success'];
},
@ -336,11 +348,36 @@ class DevicesAPI {
required String scheduleId,
}) async {
final response = await _httpService.delete(
path: ApiEndpoints.deleteSchedule.replaceAll('{deviceUuid}', deviceUuid).replaceAll('{scheduleId}', scheduleId),
path: ApiEndpoints.deleteSchedule
.replaceAll('{deviceUuid}', deviceUuid)
.replaceAll('{scheduleId}', scheduleId),
expectedResponseModel: (json) {
return json;
},
);
return response;
}
static Future getReportLogs({
required String deviceUuid,
required String code,
required String startTime,
required String endTime,
}) async {
// print(
// '---------${ApiEndpoints.reportLogs.replaceAll('{deviceUuid}', deviceUuid).replaceAll('{code}', code).replaceAll('{startTime}', startTime).replaceAll('{endTime}', endTime)}');
final response = await _httpService.get(
path: ApiEndpoints.reportLogs
.replaceAll('{deviceUuid}', deviceUuid)
.replaceAll('{code}', code)
.replaceAll('{startTime}', startTime)
.replaceAll('{endTime}', endTime),
expectedResponseModel: (json) {
print('====---------${json}');
return json;
},
);
return response;
}
}

View File

@ -1,6 +1,5 @@
//ignore_for_file: constant_identifier_names
import 'dart:ui';
import 'package:syncrow_app/features/devices/model/function_model.dart';
import 'package:syncrow_app/features/menu/view/widgets/create_home/create_home_view.dart';
import 'package:syncrow_app/features/menu/view/widgets/join_home/join_home_view.dart';
@ -50,6 +49,7 @@ enum DeviceType {
CeilingSensor,
WallSensor,
WH,
DS,
Other,
}
@ -75,11 +75,14 @@ Map<String, DeviceType> devicesTypesMap = {
"1G": DeviceType.OneGang,
"CUR": DeviceType.Curtain,
"WH": DeviceType.WH,
"DS": DeviceType.DS,
};
Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
DeviceType.AC: [
FunctionModel(
code: 'switch', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'switch',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'mode',
type: functionTypesMap['Enum'],
@ -102,7 +105,9 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
// "range": ["low", "middle", "high", "auto"]
})),
FunctionModel(
code: 'child_lock', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'child_lock',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
],
DeviceType.Gateway: [
FunctionModel(
@ -116,7 +121,9 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
"range": ["normal", "alarm"]
})),
FunctionModel(
code: 'factory_reset', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'factory_reset',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'alarm_active',
type: functionTypesMap['String'],
@ -126,7 +133,8 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
FunctionModel(
code: 'sensitivity',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "", "min": 1, "max": 10, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "", "min": 1, "max": 10, "scale": 0, "step": 1})),
],
DeviceType.DoorLock: [
FunctionModel(
@ -134,7 +142,9 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
type: functionTypesMap['Raw'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'remote_no_dp_key', type: functionTypesMap['Raw'], values: ValueModel.fromJson({})),
code: 'remote_no_dp_key',
type: functionTypesMap['Raw'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'normal_open_switch',
type: functionTypesMap['Boolean'],
@ -144,120 +154,143 @@ Map<DeviceType, List<FunctionModel>> devicesFunctionsMap = {
FunctionModel(
code: 'far_detection',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "cm", "min": 75, "max": 600, "scale": 0, "step": 75})),
values: ValueModel.fromJson(
{"unit": "cm", "min": 75, "max": 600, "scale": 0, "step": 75})),
FunctionModel(
code: 'presence_time',
type: functionTypesMap['Integer'],
values:
ValueModel.fromJson({"unit": "Min", "min": 0, "max": 65535, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "Min", "min": 0, "max": 65535, "scale": 0, "step": 1})),
FunctionModel(
code: 'motion_sensitivity_value',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
FunctionModel(
code: 'motionless_sensitivity',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "", "min": 1, "max": 5, "scale": 0, "step": 1})),
FunctionModel(
code: 'indicator', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'indicator',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
],
DeviceType.OneGang:[
DeviceType.OneGang: [
FunctionModel(
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'switch_1',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'countdown_1',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
],
DeviceType.TwoGang:[
DeviceType.TwoGang: [
FunctionModel(
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})
),
code: 'switch_1',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})
),
code: 'switch_2',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'countdown_1',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})
),
values: ValueModel.fromJson(
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
FunctionModel(
code: 'countdown_2',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})
),
values: ValueModel.fromJson(
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
],
DeviceType.ThreeGang: [
FunctionModel(
code: 'switch_1', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'switch_1',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'switch_2', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'switch_2',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'switch_3', type: functionTypesMap['Boolean'], values: ValueModel.fromJson({})),
code: 'switch_3',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})),
FunctionModel(
code: 'countdown_1',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
FunctionModel(
code: 'countdown_2',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
FunctionModel(
code: 'countdown_3',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
values: ValueModel.fromJson(
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
],
DeviceType.Curtain: [
FunctionModel(
code: 'control',
type: functionTypesMap['Enum'],
values: ValueModel.fromJson(
{"range": ["open","stop","close"]}
)
),
values: ValueModel.fromJson({
"range": ["open", "stop", "close"]
})),
FunctionModel(
code: 'percent_control',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson(
{"unit": "%", "min": 0, "max": 100, "scale": 0, "step": 1})
),
{"unit": "%", "min": 0, "max": 100, "scale": 0, "step": 1})),
],
DeviceType.WH: [
FunctionModel(
code: 'switch_1',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson({})
),
values: ValueModel.fromJson({})),
FunctionModel(
code: 'countdown_1',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson(
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})
),
{"unit": "s", "min": 0, "max": 43200, "scale": 0, "step": 1})),
FunctionModel(
code: 'relay_status',
type: functionTypesMap['Enum'],
values: ValueModel.fromJson(
{"range": [ "off", "on"]})
),
values: ValueModel.fromJson({
"range": ["off", "on"]
})),
FunctionModel(
code: 'switch_backlight',
type: functionTypesMap['Boolean'],
values: ValueModel.fromJson(
{})
),
values: ValueModel.fromJson({})),
FunctionModel(
code: 'switch_inching',
type: functionTypesMap['String'],
values: ValueModel.fromJson(
{"maxlen": 255,})
),
values: ValueModel.fromJson({
"maxlen": 255,
})),
FunctionModel(
code: 'cycle_timing',
type: functionTypesMap['Raw'],
values: ValueModel.fromJson(
{"maxlen": 255})
),
values: ValueModel.fromJson({"maxlen": 255})),
],
DeviceType.DS: [
FunctionModel(
code: 'doorcontact_state',
type: functionTypesMap['Raw'],
values: ValueModel.fromJson({})
),
FunctionModel(
code: 'battery_percentage',
type: functionTypesMap['Integer'],
values: ValueModel.fromJson({})
),
],
};
@ -404,7 +437,11 @@ List<Map<String, Object>> menuSections = [
'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsMessages,
'page': null
},
{'title': 'FAQs', 'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsFAQs, 'page': null},
{
'title': 'FAQs',
'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsFAQs,
'page': null
},
{
'title': 'Help & Feedback',
'Icon': Assets.assetsIconsMenuIconsMessagesCenterIconsHelpAndFeedback,
@ -434,7 +471,11 @@ List<Map<String, Object>> menuSections = [
'title': 'Legal Information',
'color': const Color(0xFF001B72),
'buttons': [
{'title': 'About', 'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout, 'page': null},
{
'title': 'About',
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsAbout,
'page': null
},
{
'title': 'Privacy Policy',
'Icon': Assets.assetsIconsMenuIconsLeagalInfoIconsPrivacyPolicy,