diff --git a/assets/icons/disappe_delay_icon.svg b/assets/icons/disappe_delay_icon.svg
new file mode 100644
index 00000000..c65fc5a7
--- /dev/null
+++ b/assets/icons/disappe_delay_icon.svg
@@ -0,0 +1,17 @@
+
diff --git a/assets/icons/indent_level_icon.svg b/assets/icons/indent_level_icon.svg
new file mode 100644
index 00000000..837cdac2
--- /dev/null
+++ b/assets/icons/indent_level_icon.svg
@@ -0,0 +1,13 @@
+
diff --git a/assets/icons/target_confirm_time_icon.svg b/assets/icons/target_confirm_time_icon.svg
new file mode 100644
index 00000000..61141654
--- /dev/null
+++ b/assets/icons/target_confirm_time_icon.svg
@@ -0,0 +1,21 @@
+
diff --git a/assets/icons/trigger_level_icon.svg b/assets/icons/trigger_level_icon.svg
new file mode 100644
index 00000000..56e343e8
--- /dev/null
+++ b/assets/icons/trigger_level_icon.svg
@@ -0,0 +1,23 @@
+
diff --git a/lib/pages/device_managment/all_devices/models/devices_model.dart b/lib/pages/device_managment/all_devices/models/devices_model.dart
index d07efc9b..485cb0ec 100644
--- a/lib/pages/device_managment/all_devices/models/devices_model.dart
+++ b/lib/pages/device_managment/all_devices/models/devices_model.dart
@@ -7,6 +7,7 @@ import 'package:syncrow_web/pages/device_managment/all_devices/models/room.dart'
import 'package:syncrow_web/pages/device_managment/all_devices/models/unit.dart';
import 'package:syncrow_web/pages/routines/models/ac/ac_function.dart';
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
+import 'package:syncrow_web/pages/routines/models/flush/flush_functions.dart';
import 'package:syncrow_web/pages/routines/models/gang_switches/one_gang_switch/one_gang_switch.dart';
import 'package:syncrow_web/pages/routines/models/gang_switches/three_gang_switch/three_gang_switch.dart';
import 'package:syncrow_web/pages/routines/models/gang_switches/two_gang_switch/two_gang_switch.dart';
@@ -155,13 +156,17 @@ class AllDevicesModel {
batteryLevel = int.tryParse(json['battery']?.toString() ?? '');
productName = json['productName']?.toString();
deviceTags = json['deviceTag'] != null && json['deviceTag'] is List
- ? (json['deviceTag'] as List).map((tag) => DeviceTagModel.fromJson(tag)).toList()
+ ? (json['deviceTag'] as List)
+ .map((tag) => DeviceTagModel.fromJson(tag))
+ .toList()
: [];
deviceSubSpace = json['subspace'] != null
? DeviceSubSpace.fromJson(json['subspace'])
: DeviceSubSpace(subspaceName: '');
if (json['spaces'] != null && json['spaces'] is List) {
- spaces = (json['spaces'] as List).map((space) => DeviceSpaceModel.fromJson(space)).toList();
+ spaces = (json['spaces'] as List)
+ .map((space) => DeviceSpaceModel.fromJson(space))
+ .toList();
}
}
@@ -209,7 +214,8 @@ SOS
String tempIcon = '';
if (type == DeviceType.LightBulb) {
tempIcon = Assets.lightBulb;
- } else if (type == DeviceType.CeilingSensor || type == DeviceType.WallSensor) {
+ } else if (type == DeviceType.CeilingSensor ||
+ type == DeviceType.WallSensor) {
tempIcon = Assets.sensors;
} else if (type == DeviceType.AC) {
tempIcon = Assets.ac;
@@ -239,6 +245,8 @@ SOS
// tempIcon = Assets.gang3touch;
} else if (type == DeviceType.WaterLeak) {
tempIcon = Assets.waterLeakNormal;
+ } else if (type == DeviceType.NCPS) {
+ tempIcon = Assets.sensors;
} else {
tempIcon = Assets.logoHorizontal;
}
@@ -254,51 +262,75 @@ SOS
switch (productType) {
case 'AC':
return [
- SwitchFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- ModeFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- TempSetFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- CurrentTempFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
- LevelFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- ChildLockFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ SwitchFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ModeFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ TempSetFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ CurrentTempFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
+ LevelFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ChildLockFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
];
case '1G':
return [
OneGangSwitchFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
- OneGangCountdownFunction(deviceId: uuid ?? '', deviceName: name ?? ''),
+ OneGangCountdownFunction(
+ deviceId: uuid ?? '', deviceName: name ?? ''),
];
case '2G':
return [
TwoGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
TwoGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
- TwoGangCountdown1Function(deviceId: uuid ?? '', deviceName: name ?? ''),
- TwoGangCountdown2Function(deviceId: uuid ?? '', deviceName: name ?? ''),
+ TwoGangCountdown1Function(
+ deviceId: uuid ?? '', deviceName: name ?? ''),
+ TwoGangCountdown2Function(
+ deviceId: uuid ?? '', deviceName: name ?? ''),
];
case '3G':
return [
- ThreeGangSwitch1Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- ThreeGangSwitch2Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- ThreeGangSwitch3Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- ThreeGangCountdown1Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- ThreeGangCountdown2Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- ThreeGangCountdown3Function(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ThreeGangSwitch1Function(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ThreeGangSwitch2Function(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ThreeGangSwitch3Function(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ThreeGangCountdown1Function(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ThreeGangCountdown2Function(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ ThreeGangCountdown3Function(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
];
case 'WPS':
return [
//IF Functions
- PresenceStateFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
- CurrentDistanceFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
- IlluminanceValueFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
- PresenceTimeFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
+ PresenceStateFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
+ CurrentDistanceFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
+ IlluminanceValueFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
+ PresenceTimeFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
//THEN Functions
- FarDetectionFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
- MotionSensitivityFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
- MotionLessSensitivityFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
- IndicatorFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
- NoOneTimeFunction(deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ FarDetectionFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ MotionSensitivityFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ MotionLessSensitivityFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ IndicatorFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'BOTH'),
+ NoOneTimeFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
];
case 'GW':
return [
@@ -323,6 +355,30 @@ SOS
uuid: uuid ?? '',
name: name ?? '',
);
+ case 'NCPS':
+ return [
+ FlushPresenceDelayFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF',),
+
+ FlushIlluminanceFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'IF'),
+ //THEN Functions
+ FlushSensitivityFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ FlushNearDetectionFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ FlushMaxDetectDistFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ FlushTargetConfirmTimeFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ FlushDisappeDelayFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ FlushIndentLevelFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ FlushTriggerLevelFunction(
+ deviceId: uuid ?? '', deviceName: name ?? '', type: 'THEN'),
+ ];
+
default:
return [];
}
@@ -454,5 +510,6 @@ SOS
"3GT": DeviceType.ThreeTouch,
"GD": DeviceType.GarageDoor,
"WL": DeviceType.WaterLeak,
+ "NCPS": DeviceType.NCPS,
};
}
diff --git a/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart b/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart
index 975af0e8..bf97005d 100644
--- a/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart
+++ b/lib/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart
@@ -97,3 +97,7 @@ class FlushMountedPresenceSensorModel {
);
}
}
+
+
+
+
diff --git a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart
index 025de303..9083ffbe 100644
--- a/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart
+++ b/lib/pages/device_managment/garage_door/bloc/garage_door_bloc.dart
@@ -106,14 +106,14 @@ class GarageDoorBloc extends Bloc {
ScheduleEntry newSchedule = ScheduleEntry(
category: event.category,
time: formatTimeOfDayToISO(event.time),
- function: Status(code: 'switch_1', value: event.functionOn),
+ function: Status(code: 'doorcontact_state', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
bool success =
await DevicesManagementApi().addScheduleRecord(newSchedule, deviceId);
if (success) {
add(FetchGarageDoorSchedulesEvent(
- deviceId: deviceId, category: 'switch_1'));
+ deviceId: deviceId, category: 'doorcontact_state'));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
@@ -149,7 +149,8 @@ class GarageDoorBloc extends Bloc {
final updatedSchedules = deviceStatus.schedules?.map((schedule) {
if (schedule.scheduleId == event.scheduleId) {
return schedule.copyWith(
- function: Status(code: 'switch_1', value: event.functionOn),
+ function:
+ Status(code: 'doorcontact_state', value: event.functionOn),
enable: event.enable,
);
}
@@ -274,7 +275,8 @@ class GarageDoorBloc extends Bloc {
Future _onBatchControl(
GarageDoorBatchControlEvent event, Emitter emit) async {
- final oldValue = event.code == 'switch_1' ? deviceStatus.switch1 : false;
+ final oldValue =
+ event.code == 'doorcontact_state' ? deviceStatus.switch1 : false;
_updateLocalValue(event.code, event.value);
emit(GarageDoorBatchStatusLoaded(deviceStatus));
@@ -409,7 +411,7 @@ class GarageDoorBloc extends Bloc {
void _revertValue(
String code, dynamic oldValue, Emitter emit) {
switch (code) {
- case 'switch_1':
+ case 'doorcontact_state':
if (oldValue is bool) {
deviceStatus = deviceStatus.copyWith(switch1: oldValue);
}
@@ -468,10 +470,11 @@ class GarageDoorBloc extends Bloc {
deviceStatus = deviceStatus.copyWith(voiceControl1: value);
}
break;
- case 'door_contact_state':
+ case 'doorcontact_state':
if (value is bool) {
deviceStatus = deviceStatus.copyWith(doorContactState: value);
}
+
default:
break;
}
@@ -490,14 +493,14 @@ class GarageDoorBloc extends Bloc {
scheduleId: event.scheduleId,
category: event.category,
time: formatTimeOfDayToISO(event.time),
- function: Status(code: 'switch_1', value: event.functionOn),
+ function: Status(code: 'doorcontact_state', value: event.functionOn),
days: ScheduleModel.convertSelectedDaysToStrings(event.selectedDays),
);
bool success = await DevicesManagementApi()
.editScheduleRecord(deviceId, newSchedule);
if (success) {
add(FetchGarageDoorSchedulesEvent(
- deviceId: deviceId, category: 'switch_1'));
+ deviceId: deviceId, category: 'doorcontact_state'));
} else {
emit(GarageDoorLoadedState(status: deviceStatus));
}
diff --git a/lib/pages/device_managment/garage_door/view/garage_door_control_view.dart b/lib/pages/device_managment/garage_door/view/garage_door_control_view.dart
index 886ca9ae..ae2fc9e4 100644
--- a/lib/pages/device_managment/garage_door/view/garage_door_control_view.dart
+++ b/lib/pages/device_managment/garage_door/view/garage_door_control_view.dart
@@ -14,7 +14,8 @@ import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/extension/build_context_x.dart';
import 'package:syncrow_web/utils/helpers/responsice_layout_helper/responsive_layout_helper.dart';
-class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout {
+class GarageDoorControlView extends StatelessWidget
+ with HelperResponsiveLayout {
final String deviceId;
const GarageDoorControlView({required this.deviceId, super.key});
@@ -22,7 +23,8 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
@override
Widget build(BuildContext context) {
return BlocProvider(
- create: (context) => GarageDoorBloc(deviceId: deviceId)..add(GarageDoorInitialEvent(deviceId)),
+ create: (context) => GarageDoorBloc(deviceId: deviceId)
+ ..add(GarageDoorInitialEvent(deviceId)),
child: BlocBuilder(
builder: (context, state) {
if (state is GarageDoorLoadingState) {
@@ -34,7 +36,9 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
garageDoorSensor: true,
onRowTap: (index) {},
onClose: () {
- context.read().add(BackToGarageDoorGridViewEvent());
+ context
+ .read()
+ .add(BackToGarageDoorGridViewEvent());
},
);
} else if (state is GarageDoorLoadedState) {
@@ -71,11 +75,14 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
children: [
IconNameStatusContainer(
isFullIcon: false,
- name: status.switch1 ? 'Opened' : 'Closed',
- icon: status.switch1 ? Assets.openedDoor : Assets.closedDoor,
+ name: status.doorContactState ? 'Opened' : 'Closed',
+ icon: status.doorContactState ? Assets.openedDoor : Assets.closedDoor,
onTap: () {
context.read().add(
- GarageDoorControlEvent(deviceId: status.uuid, value: !status.switch1, code: 'switch_1'),
+ GarageDoorControlEvent(
+ deviceId: status.uuid,
+ value: !status.switch1,
+ code: 'doorcontact_state'),
);
},
status: status.switch1,
@@ -84,7 +91,8 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
IconNameStatusContainer(
onTap: () {
context.read().add(
- FetchGarageDoorSchedulesEvent(deviceId: deviceId, category: 'switch_1'),
+ FetchGarageDoorSchedulesEvent(
+ deviceId: deviceId, category: 'doorcontact_state'),
);
showDialog(
context: context,
@@ -107,7 +115,9 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
children: [
IconButton(
onPressed: () {
- context.read().add(DecreaseGarageDoorDelayEvent(deviceId: status.uuid));
+ context
+ .read()
+ .add(DecreaseGarageDoorDelayEvent(deviceId: status.uuid));
},
icon: const Icon(
Icons.remove,
@@ -125,7 +135,8 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
),
Text(
'h',
- style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
+ style: context.textTheme.bodySmall!
+ .copyWith(color: ColorsManager.blackColor),
),
Text(
(status.delay.inMinutes % 60).toString().padLeft(2, '0'),
@@ -136,11 +147,14 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
),
Text(
'm',
- style: context.textTheme.bodySmall!.copyWith(color: ColorsManager.blackColor),
+ style: context.textTheme.bodySmall!
+ .copyWith(color: ColorsManager.blackColor),
),
IconButton(
onPressed: () {
- context.read().add(IncreaseGarageDoorDelayEvent(deviceId: status.uuid));
+ context
+ .read()
+ .add(IncreaseGarageDoorDelayEvent(deviceId: status.uuid));
},
icon: const Icon(
Icons.add,
@@ -158,7 +172,9 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
onChange: (value) {
context.read().add(
GarageDoorControlEvent(
- deviceId: status.uuid, value: value ? status.delay.inSeconds : 0, code: 'countdown_1'),
+ deviceId: status.uuid,
+ value: value ? status.delay.inSeconds : 0,
+ code: 'countdown_1'),
);
},
),
@@ -167,7 +183,8 @@ class GarageDoorControlView extends StatelessWidget with HelperResponsiveLayout
name: 'Records',
icon: Assets.records,
onTap: () {
- context.read().add(FetchGarageDoorRecordsEvent(code: 'switch_1', deviceId: status.uuid));
+ context.read().add(FetchGarageDoorRecordsEvent(
+ code: 'doorcontact_state', deviceId: status.uuid));
},
status: false,
textColor: ColorsManager.blackColor,
diff --git a/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart b/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart
index b1afbc12..a94a312b 100644
--- a/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart
+++ b/lib/pages/routines/helper/dialog_helper/device_dialog_helper.dart
@@ -4,6 +4,7 @@ import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ac_dialog.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/ceiling_sensor_helper.dart';
+import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_presence_sensor.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/gateway/gateway_helper.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/one_gang_switch_dialog.dart';
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/three_gang_switch_dialog.dart';
@@ -116,6 +117,15 @@ class DeviceDialogHelper {
deviceSelectedFunctions: deviceSelectedFunctions,
device: data['device'],
);
+ case 'NCPS':
+ return FlushPresenceSensor.showFlushFunctionsDialog(
+ context: context,
+ functions: functions,
+ uniqueCustomId: data['uniqueCustomId'],
+ deviceSelectedFunctions: deviceSelectedFunctions,
+ dialogType: dialogType,
+ device: data['device'],
+ );
default:
return null;
diff --git a/lib/pages/routines/models/flush/flush_functions.dart b/lib/pages/routines/models/flush/flush_functions.dart
new file mode 100644
index 00000000..5013c0b8
--- /dev/null
+++ b/lib/pages/routines/models/flush/flush_functions.dart
@@ -0,0 +1,407 @@
+import 'package:syncrow_web/pages/device_managment/flush_mounted_presence_sensor/models/flush_mounted_presence_sensor_model.dart';
+import 'package:syncrow_web/pages/routines/models/device_functions.dart';
+import 'package:syncrow_web/pages/routines/models/flush/flush_operational_value.dart';
+import 'package:syncrow_web/utils/constants/assets.dart';
+
+abstract class FlushFunctions
+ extends DeviceFunction {
+ final String type;
+
+ FlushFunctions({
+ required super.deviceId,
+ required super.deviceName,
+ required super.code,
+ required super.operationName,
+ required super.icon,
+ required this.type,
+ });
+
+ List getOperationalValues();
+}
+
+class FlushPresenceDelayFunction extends FlushFunctions {
+ final int min;
+ FlushPresenceDelayFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 0,
+ super(
+ code: FlushMountedPresenceSensorModel.codePresenceState,
+ operationName: 'Presence State',
+ icon: Assets.presenceStateIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ return [
+ FlushOperationalValue(
+ icon: Assets.nobodyTime,
+ description: 'None',
+ value: "none",
+ ),
+ FlushOperationalValue(
+ icon: Assets.presenceStateIcon,
+ description: 'Presence',
+ value: 'presence',
+ ),
+ ];
+ }
+}
+
+class FlushSensiReduceFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+
+ FlushSensiReduceFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 1,
+ max = 5,
+ step = 1,
+ super(
+ code: FlushMountedPresenceSensorModel.codeSensiReduce,
+ operationName: 'Sensitivity Reduction',
+ icon: Assets.motionlessDetectionSensitivityIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ return List.generate(
+ (max - min) ~/ step + 1,
+ (index) => FlushOperationalValue(
+ icon: Assets.currentDistanceIcon,
+ description: '${min + (index * step)}',
+ value: min + (index * step),
+ ));
+ }
+}
+
+class FlushNoneDelayFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final String unit;
+
+ FlushNoneDelayFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 10,
+ max = 10000,
+ unit = '秒',
+ super(
+ code: FlushMountedPresenceSensorModel.codeNoneDelay,
+ operationName: 'None Delay',
+ icon: Assets.nobodyTime,
+ );
+
+ @override
+ List getOperationalValues() {
+ return [
+ FlushOperationalValue(
+ icon: icon,
+ description: 'Custom $unit',
+ value: null,
+ )
+ ];
+ }
+}
+
+class FlushIlluminanceFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+
+ FlushIlluminanceFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 0,
+ max = 2000,
+ step = 0,
+ super(
+ code: FlushMountedPresenceSensorModel.codeIlluminance,
+ operationName: 'Illuminance',
+ icon: Assets.IlluminanceIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ List values = [];
+ for (int lux = min; lux <= max; lux += step) {
+ values.add(FlushOperationalValue(
+ icon: Assets.IlluminanceIcon,
+ description: "$lux Lux",
+ value: lux,
+ ));
+ }
+ return values;
+ }
+}
+
+class FlushOccurDistReduceFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+
+ FlushOccurDistReduceFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 0,
+ max = 100,
+ step = 1,
+ super(
+ code: FlushMountedPresenceSensorModel.codeOccurDistReduce,
+ operationName: 'Occurrence Distance Reduction',
+ icon: Assets.assetsTempreture,
+ );
+
+ @override
+ List getOperationalValues() {
+ return List.generate(
+ (max - min) ~/ step + 1,
+ (index) => FlushOperationalValue(
+ icon: Assets.assetsTempreture,
+ description: '${min + (index * step)}',
+ value: min + (index * step),
+ ));
+ }
+}
+
+// ==== then functions ====
+class FlushSensitivityFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+
+ FlushSensitivityFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 1,
+ max = 9,
+ step = 1,
+ super(
+ code: FlushMountedPresenceSensorModel.codeSensitivity,
+ operationName: 'Sensitivity',
+ icon: Assets.sensitivity,
+ );
+
+ @override
+ List getOperationalValues() {
+ return List.generate(
+ (max - min) ~/ step + 1,
+ (index) => FlushOperationalValue(
+ icon: Assets.motionDetectionSensitivityValueIcon,
+ description: '${min + (index * step)}',
+ value: min + (index * step),
+ ));
+ }
+}
+
+class FlushNearDetectionFunction extends FlushFunctions {
+ final int min;
+ final double max;
+ final int step;
+ final String unit;
+
+ FlushNearDetectionFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 0,
+ max = 9.5,
+ step = 1,
+ unit = 'm',
+ super(
+ code: FlushMountedPresenceSensorModel.codeNearDetection,
+ operationName: 'Nearest Detect Dist',
+ icon: Assets.currentDistanceIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ final values = [];
+ for (var value = min; value <= max; value += step) {
+ values.add(FlushOperationalValue(
+ icon: Assets.nobodyTime,
+ description: '$value $unit',
+ value: value * 10,
+ ));
+ }
+ return values;
+ }
+}
+
+class FlushMaxDetectDistFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+ final String unit;
+
+ FlushMaxDetectDistFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 75,
+ max = 600,
+ step = 75,
+ unit = 'cm',
+ super(
+ code: FlushMountedPresenceSensorModel.codeFarDetection,
+ operationName: 'Max Detect Dist',
+ icon: Assets.currentDistanceIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ final values = [];
+ for (var value = min; value <= max; value += step) {
+ values.add(FlushOperationalValue(
+ icon: Assets.nobodyTime,
+ description: '$value $unit',
+ value: value,
+ ));
+ }
+ return values;
+ }
+}
+
+class FlushTargetConfirmTimeFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+ final String unit;
+
+ FlushTargetConfirmTimeFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 75,
+ max = 600,
+ step = 75,
+ unit = 'cm',
+ super(
+ code: FlushMountedPresenceSensorModel.codePresenceDelay,
+ operationName: 'Target Confirm Time',
+ icon: Assets.targetConfirmTimeIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ final values = [];
+ for (var value = min; value <= max; value += step) {
+ values.add(FlushOperationalValue(
+ icon: Assets.nobodyTime,
+ description: '$value $unit',
+ value: value,
+ ));
+ }
+ return values;
+ }
+}
+
+class FlushDisappeDelayFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+ final String unit;
+
+ FlushDisappeDelayFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 75,
+ max = 600,
+ step = 75,
+ unit = 'cm',
+ super(
+ code: FlushMountedPresenceSensorModel.codeNoneDelay,
+ operationName: 'Disappe Delay',
+ icon: Assets.DisappeDelayIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ final values = [];
+ for (var value = min; value <= max; value += step) {
+ values.add(FlushOperationalValue(
+ icon: Assets.nobodyTime,
+ description: '$value $unit',
+ value: value,
+ ));
+ }
+ return values;
+ }
+}
+
+class FlushIndentLevelFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+ final String unit;
+
+ FlushIndentLevelFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 75,
+ max = 600,
+ step = 75,
+ unit = 'cm',
+ super(
+ code: FlushMountedPresenceSensorModel.codeOccurDistReduce,
+ operationName: 'Indent Level',
+ icon: Assets.indentLevelIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ final values = [];
+ for (var value = min; value <= max; value += step) {
+ values.add(FlushOperationalValue(
+ icon: Assets.nobodyTime,
+ description: '$value $unit',
+ value: value,
+ ));
+ }
+ return values;
+ }
+}
+
+class FlushTriggerLevelFunction extends FlushFunctions {
+ final int min;
+ final int max;
+ final int step;
+ final String unit;
+
+ FlushTriggerLevelFunction({
+ required super.deviceId,
+ required super.deviceName,
+ required super.type,
+ }) : min = 75,
+ max = 600,
+ step = 75,
+ unit = 'cm',
+ super(
+ code: FlushMountedPresenceSensorModel.codeSensiReduce,
+ operationName: 'Trigger Level',
+ icon: Assets.triggerLevelIcon,
+ );
+
+ @override
+ List getOperationalValues() {
+ final values = [];
+ for (var value = min; value <= max; value += step) {
+ values.add(FlushOperationalValue(
+ icon: Assets.nobodyTime,
+ description: '$value $unit',
+ value: value,
+ ));
+ }
+ return values;
+ }
+}
diff --git a/lib/pages/routines/models/flush/flush_operational_value.dart b/lib/pages/routines/models/flush/flush_operational_value.dart
new file mode 100644
index 00000000..af96d35b
--- /dev/null
+++ b/lib/pages/routines/models/flush/flush_operational_value.dart
@@ -0,0 +1,11 @@
+class FlushOperationalValue {
+ final String icon;
+ final String description;
+ final dynamic value;
+
+ FlushOperationalValue({
+ required this.icon,
+ required this.description,
+ required this.value,
+ });
+}
diff --git a/lib/pages/routines/widgets/if_container.dart b/lib/pages/routines/widgets/if_container.dart
index f7a4ddc1..884c8d10 100644
--- a/lib/pages/routines/widgets/if_container.dart
+++ b/lib/pages/routines/widgets/if_container.dart
@@ -28,10 +28,12 @@ class IfContainer extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text('IF',
- style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
+ style: TextStyle(
+ fontSize: 18, fontWeight: FontWeight.bold)),
if (state.isAutomation && state.ifItems.isNotEmpty)
AutomationOperatorSelector(
- selectedOperator: state.selectedAutomationOperator),
+ selectedOperator:
+ state.selectedAutomationOperator),
],
),
const SizedBox(height: 16),
@@ -55,16 +57,17 @@ class IfContainer extends StatelessWidget {
(index) => GestureDetector(
onTap: () async {
if (!state.isTabToRun) {
- final result = await DeviceDialogHelper.showDeviceDialog(
- context: context,
- data: state.ifItems[index],
- removeComparetors: false,
- dialogType: "IF");
+ final result = await DeviceDialogHelper
+ .showDeviceDialog(
+ context: context,
+ data: state.ifItems[index],
+ removeComparetors: false,
+ dialogType: "IF");
if (result != null) {
- context
- .read()
- .add(AddToIfContainer(state.ifItems[index], false));
+ context.read().add(
+ AddToIfContainer(
+ state.ifItems[index], false));
} else if (![
'AC',
'1G',
@@ -73,25 +76,32 @@ class IfContainer extends StatelessWidget {
'WPS',
'GW',
'CPS',
- ].contains(state.ifItems[index]['productType'])) {
- context
- .read()
- .add(AddToIfContainer(state.ifItems[index], false));
+ 'NCPS'
+ ].contains(state.ifItems[index]
+ ['productType'])) {
+
+ context.read().add(
+ AddToIfContainer(
+ state.ifItems[index], false));
}
}
},
child: DraggableCard(
- imagePath: state.ifItems[index]['imagePath'] ?? '',
+ imagePath:
+ state.ifItems[index]['imagePath'] ?? '',
title: state.ifItems[index]['title'] ?? '',
deviceData: state.ifItems[index],
- padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8),
+ padding: const EdgeInsets.symmetric(
+ horizontal: 4, vertical: 8),
isFromThen: false,
isFromIf: true,
onRemove: () {
- context.read().add(RemoveDragCard(
- index: index,
- isFromThen: false,
- key: state.ifItems[index]['uniqueCustomId']));
+ context.read().add(
+ RemoveDragCard(
+ index: index,
+ isFromThen: false,
+ key: state.ifItems[index]
+ ['uniqueCustomId']));
},
),
)),
@@ -112,7 +122,9 @@ class IfContainer extends StatelessWidget {
if (!state.isTabToRun) {
if (mutableData['deviceId'] == 'tab_to_run') {
- context.read().add(AddToIfContainer(mutableData, true));
+ context
+ .read()
+ .add(AddToIfContainer(mutableData, true));
} else {
final result = await DeviceDialogHelper.showDeviceDialog(
dialogType: 'IF',
@@ -121,10 +133,14 @@ class IfContainer extends StatelessWidget {
removeComparetors: false);
if (result != null) {
- context.read().add(AddToIfContainer(mutableData, false));
- } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW', 'CPS']
+ context
+ .read()
+ .add(AddToIfContainer(mutableData, false));
+ } else if (!['AC', '1G', '2G', '3G', 'WPS', 'GW', 'CPS', 'NCPS']
.contains(mutableData['productType'])) {
- context.read().add(AddToIfContainer(mutableData, false));
+ context
+ .read()
+ .add(AddToIfContainer(mutableData, false));
}
}
}
@@ -170,7 +186,9 @@ class AutomationOperatorSelector extends StatelessWidget {
),
),
onPressed: () {
- context.read().add(const ChangeAutomationOperator(operator: 'or'));
+ context
+ .read()
+ .add(const ChangeAutomationOperator(operator: 'or'));
},
),
Container(
@@ -196,7 +214,9 @@ class AutomationOperatorSelector extends StatelessWidget {
),
),
onPressed: () {
- context.read().add(const ChangeAutomationOperator(operator: 'and'));
+ context
+ .read()
+ .add(const ChangeAutomationOperator(operator: 'and'));
},
),
],
diff --git a/lib/pages/routines/widgets/routine_devices.dart b/lib/pages/routines/widgets/routine_devices.dart
index 3294a73a..9192b422 100644
--- a/lib/pages/routines/widgets/routine_devices.dart
+++ b/lib/pages/routines/widgets/routine_devices.dart
@@ -17,7 +17,16 @@ class _RoutineDevicesState extends State {
context.read().add(FetchDevicesInRoutine());
}
- static const _allowedProductTypes = {'AC', '1G', '2G', '3G', 'WPS', 'GW', 'CPS'};
+ static const _allowedProductTypes = {
+ 'AC',
+ '1G',
+ '2G',
+ '3G',
+ 'WPS',
+ 'GW',
+ 'CPS',
+ 'NCPS'
+ };
@override
Widget build(BuildContext context) {
@@ -34,7 +43,8 @@ class _RoutineDevicesState extends State {
});
final deviceList = state.devices
- .where((device) => _allowedProductTypes.contains(device.productType))
+ .where(
+ (device) => _allowedProductTypes.contains(device.productType))
.toList();
return Wrap(
@@ -51,12 +61,16 @@ class _RoutineDevicesState extends State {
'productType': device.productType,
'functions': device.functions,
'uniqueCustomId': '',
- 'tag': device.deviceTags!.isNotEmpty ? device.deviceTags![0].name : '',
+ 'tag': device.deviceTags!.isNotEmpty
+ ? device.deviceTags![0].name
+ : '',
'subSpace': device.deviceSubSpace?.subspaceName ?? '',
};
if (state.searchText != null && state.searchText!.isNotEmpty) {
- return device.name!.toLowerCase().contains(state.searchText!.toLowerCase())
+ return device.name!
+ .toLowerCase()
+ .contains(state.searchText!.toLowerCase())
? DraggableCard(
imagePath: deviceData['imagePath'] as String,
title: deviceData['title'] as String,
diff --git a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart
new file mode 100644
index 00000000..1a96cfbb
--- /dev/null
+++ b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_operational_values_list.dart
@@ -0,0 +1,70 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
+import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
+import 'package:syncrow_web/pages/routines/models/device_functions.dart';
+import 'package:syncrow_web/pages/routines/models/flush/flush_operational_value.dart';
+import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/wall_sensor/time_wheel.dart';
+
+class FlushOperationalValuesList extends StatelessWidget {
+ final List values;
+ final dynamic selectedValue;
+ final AllDevicesModel? device;
+ final String operationName;
+ final String selectCode;
+ final ValueChanged onSelect;
+ const FlushOperationalValuesList({
+ required this.values,
+ required this.selectedValue,
+ required this.device,
+ required this.operationName,
+ required this.selectCode,
+ required this.onSelect,
+ super.key,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return ListView.builder(
+ padding: const EdgeInsets.all(20),
+ itemCount: values.length,
+ itemBuilder: (context, index) =>
+ _buildValueItem(context, values[index]),
+ );
+ }
+
+
+
+ Widget _buildValueItem(BuildContext context, FlushOperationalValue value) {
+ return Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(child: _buildValueDescription(value)),
+ _buildValueRadio(context, value),
+ ],
+ ),
+ );
+ }
+
+
+
+
+ Widget _buildValueDescription(FlushOperationalValue value) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
+ child: Text(value.description),
+ );
+ }
+
+ Widget _buildValueRadio(context, FlushOperationalValue value) {
+ return Radio(
+ value: value.value,
+ groupValue: selectedValue,
+ onChanged: (_) => onSelect(value));
+ }
+
+
+}
diff --git a/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_presence_sensor.dart b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_presence_sensor.dart
new file mode 100644
index 00000000..bf2146ad
--- /dev/null
+++ b/lib/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_presence_sensor.dart
@@ -0,0 +1,208 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:syncrow_web/pages/device_managment/all_devices/models/devices_model.dart';
+import 'package:syncrow_web/pages/routines/bloc/functions_bloc/functions_bloc_bloc.dart';
+import 'package:syncrow_web/pages/routines/bloc/routine_bloc/routine_bloc.dart';
+import 'package:syncrow_web/pages/routines/models/device_functions.dart';
+import 'package:syncrow_web/pages/routines/models/flush/flush_functions.dart';
+import 'package:syncrow_web/pages/routines/widgets/dialog_footer.dart';
+import 'package:syncrow_web/pages/routines/widgets/dialog_header.dart';
+import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/flush_presence_sensor/flush_value_selector_widget.dart';
+import 'package:syncrow_web/utils/color_manager.dart';
+import 'package:syncrow_web/utils/extension/build_context_x.dart';
+
+class FlushPresenceSensor extends StatefulWidget {
+ final List functions;
+ final AllDevicesModel? device;
+ final List? deviceSelectedFunctions;
+ final String? uniqueCustomId;
+ final String dialogType;
+ final bool removeComparetors;
+
+ const FlushPresenceSensor({
+ super.key,
+ required this.functions,
+ this.device,
+ this.deviceSelectedFunctions,
+ this.uniqueCustomId,
+ required this.dialogType,
+ this.removeComparetors = false,
+ });
+
+ static Future