mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 07:07:19 +00:00
Refactor ceiling sensor functions and update slider helper mappings for improved value handling
This commit is contained in:
@ -1,7 +1,6 @@
|
|||||||
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
import 'package:syncrow_web/pages/routines/models/device_functions.dart';
|
||||||
import 'package:syncrow_web/utils/constants/assets.dart';
|
import 'package:syncrow_web/utils/constants/assets.dart';
|
||||||
|
|
||||||
// TODO: functions in conditions / status in actions
|
|
||||||
class CpsOperationalValue {
|
class CpsOperationalValue {
|
||||||
final String icon;
|
final String icon;
|
||||||
final String description;
|
final String description;
|
||||||
@ -223,7 +222,6 @@ final class CpsSpatialMotionValueFunction extends CpsFunctions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class CpsMaxDistanceOfDetectionFunction extends CpsFunctions {
|
final class CpsMaxDistanceOfDetectionFunction extends CpsFunctions {
|
||||||
// confirm with BE
|
|
||||||
CpsMaxDistanceOfDetectionFunction({
|
CpsMaxDistanceOfDetectionFunction({
|
||||||
required super.deviceId,
|
required super.deviceId,
|
||||||
required super.deviceName,
|
required super.deviceName,
|
||||||
@ -267,7 +265,7 @@ final class CpsMaxDistanceOfStaticDetectionFunction extends CpsFunctions {
|
|||||||
max = 10.0,
|
max = 10.0,
|
||||||
step = 0.5,
|
step = 0.5,
|
||||||
super(
|
super(
|
||||||
code: 'static_max_dis', // 0 / 500
|
code: 'static_max_dis',
|
||||||
operationName: 'Maximum Distance Of Static Detection',
|
operationName: 'Maximum Distance Of Static Detection',
|
||||||
icon: Assets.currentDistanceIcon,
|
icon: Assets.currentDistanceIcon,
|
||||||
);
|
);
|
||||||
@ -302,7 +300,7 @@ final class CpsDetectionRangeFunction extends CpsFunctions {
|
|||||||
max = 25.5,
|
max = 25.5,
|
||||||
step = 0.1,
|
step = 0.1,
|
||||||
super(
|
super(
|
||||||
code: 'moving_range', // just then
|
code: 'moving_range',
|
||||||
operationName: 'Detection Range',
|
operationName: 'Detection Range',
|
||||||
icon: Assets.farDetection,
|
icon: Assets.farDetection,
|
||||||
);
|
);
|
||||||
@ -372,7 +370,7 @@ final class CpsPresenceJudgementThrsholdFunction extends CpsFunctions {
|
|||||||
max = 255,
|
max = 255,
|
||||||
step = 5,
|
step = 5,
|
||||||
super(
|
super(
|
||||||
code: 'presence_reference', // max 255 // change widget
|
code: 'presence_reference',
|
||||||
operationName: 'Presence Judgement Threshold',
|
operationName: 'Presence Judgement Threshold',
|
||||||
icon: Assets.presenceJudgementThrshold,
|
icon: Assets.presenceJudgementThrshold,
|
||||||
);
|
);
|
||||||
@ -403,7 +401,7 @@ final class CpsMotionAmplitudeTriggerThresholdFunction extends CpsFunctions {
|
|||||||
max = 255,
|
max = 255,
|
||||||
step = 5,
|
step = 5,
|
||||||
super(
|
super(
|
||||||
code: 'moving_reference', // max 255 // change widget
|
code: 'moving_reference',
|
||||||
operationName: 'Motion Amplitude Trigger Threshold',
|
operationName: 'Motion Amplitude Trigger Threshold',
|
||||||
icon: Assets.presenceJudgementThrshold,
|
icon: Assets.presenceJudgementThrshold,
|
||||||
);
|
);
|
||||||
@ -434,7 +432,7 @@ final class CpsPerpetualBoundaryFunction extends CpsFunctions {
|
|||||||
max = 5.00,
|
max = 5.00,
|
||||||
step = 0.50,
|
step = 0.50,
|
||||||
super(
|
super(
|
||||||
code: 'perceptual_boundary', // 0 / 500
|
code: 'perceptual_boundary',
|
||||||
operationName: 'Perpetual Boundary',
|
operationName: 'Perpetual Boundary',
|
||||||
icon: Assets.boundary,
|
icon: Assets.boundary,
|
||||||
);
|
);
|
||||||
@ -469,7 +467,7 @@ final class CpsMotionTriggerBoundaryFunction extends CpsFunctions {
|
|||||||
max = 5.0,
|
max = 5.0,
|
||||||
step = 0.5,
|
step = 0.5,
|
||||||
super(
|
super(
|
||||||
code: 'moving_boundary', // 0 / 500 / step 50
|
code: 'moving_boundary',
|
||||||
operationName: 'Motion Trigger Boundary',
|
operationName: 'Motion Trigger Boundary',
|
||||||
icon: Assets.motionMeter,
|
icon: Assets.motionMeter,
|
||||||
);
|
);
|
||||||
@ -504,7 +502,7 @@ final class CpsMotionTriggerTimeFunction extends CpsFunctions {
|
|||||||
max = 2.0,
|
max = 2.0,
|
||||||
step = 0.1,
|
step = 0.1,
|
||||||
super(
|
super(
|
||||||
code: 'moving_rigger_time', // 0 / 2000 steps 10
|
code: 'moving_rigger_time',
|
||||||
operationName: 'Motion Trigger Time',
|
operationName: 'Motion Trigger Time',
|
||||||
icon: Assets.motionMeter,
|
icon: Assets.motionMeter,
|
||||||
);
|
);
|
||||||
@ -539,7 +537,7 @@ final class CpsMotionToStaticTimeFunction extends CpsFunctions {
|
|||||||
max = 50.0,
|
max = 50.0,
|
||||||
step = 1.0,
|
step = 1.0,
|
||||||
super(
|
super(
|
||||||
code: 'moving_static_time', // 0 / 6000 steps 100
|
code: 'moving_static_time',
|
||||||
operationName: 'Motion To Static Time',
|
operationName: 'Motion To Static Time',
|
||||||
icon: Assets.motionMeter,
|
icon: Assets.motionMeter,
|
||||||
);
|
);
|
||||||
@ -574,7 +572,7 @@ final class CpsEnteringNoBodyStateTimeFunction extends CpsFunctions {
|
|||||||
max = 300.0,
|
max = 300.0,
|
||||||
step = 5.0,
|
step = 5.0,
|
||||||
super(
|
super(
|
||||||
code: 'none_body_time', // 0 / 300000 / steps 500
|
code: 'none_body_time',
|
||||||
operationName: 'Entering Nobody State Time',
|
operationName: 'Entering Nobody State Time',
|
||||||
icon: Assets.motionMeter,
|
icon: Assets.motionMeter,
|
||||||
);
|
);
|
||||||
@ -606,7 +604,7 @@ final class CpsSelfTestResultFunctions extends CpsFunctions {
|
|||||||
required super.deviceName,
|
required super.deviceName,
|
||||||
required super.type,
|
required super.type,
|
||||||
}) : super(
|
}) : super(
|
||||||
code: 'checking_result', // just in action
|
code: 'checking_result',
|
||||||
operationName: 'Self-Test Result',
|
operationName: 'Self-Test Result',
|
||||||
icon: Assets.selfTestResult,
|
icon: Assets.selfTestResult,
|
||||||
);
|
);
|
||||||
@ -828,7 +826,7 @@ class CpsPresenceStatusFunctions extends CpsFunctions {
|
|||||||
required super.deviceName,
|
required super.deviceName,
|
||||||
required super.type,
|
required super.type,
|
||||||
}) : super(
|
}) : super(
|
||||||
code: 'presence_state', // just in action
|
code: 'presence_state',
|
||||||
operationName: 'Presence Status',
|
operationName: 'Presence Status',
|
||||||
icon: Assets.presenceSensor,
|
icon: Assets.presenceSensor,
|
||||||
);
|
);
|
||||||
@ -864,7 +862,7 @@ final class CpsSportsParaFunction extends CpsFunctions {
|
|||||||
max = 100,
|
max = 100,
|
||||||
step = 1,
|
step = 1,
|
||||||
super(
|
super(
|
||||||
code: 'sports_para', // just in action
|
code: 'sports_para',
|
||||||
operationName: 'Sports Para',
|
operationName: 'Sports Para',
|
||||||
icon: Assets.sportsPara,
|
icon: Assets.sportsPara,
|
||||||
);
|
);
|
||||||
|
@ -11,6 +11,7 @@ import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_senso
|
|||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_slider_selector.dart';
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_slider_selector.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart';
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_dialog_value_selector.dart';
|
||||||
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart';
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_functions_list.dart';
|
||||||
|
import 'package:syncrow_web/pages/routines/widgets/routine_dialogs/ceiling_sensor/cps_slider_helpers.dart';
|
||||||
|
|
||||||
class CeilingSensorDialog extends StatefulWidget {
|
class CeilingSensorDialog extends StatefulWidget {
|
||||||
const CeilingSensorDialog({
|
const CeilingSensorDialog({
|
||||||
@ -76,7 +77,8 @@ class _CeilingSensorDialogState extends State<CeilingSensorDialog> {
|
|||||||
? () {
|
? () {
|
||||||
context.read<RoutineBloc>().add(
|
context.read<RoutineBloc>().add(
|
||||||
AddFunctionToRoutine(
|
AddFunctionToRoutine(
|
||||||
state.addedFunctions,
|
_updateValuesForAddedFunctions(
|
||||||
|
state.addedFunctions),
|
||||||
'${widget.uniqueCustomId}',
|
'${widget.uniqueCustomId}',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -150,15 +152,58 @@ class _CeilingSensorDialogState extends State<CeilingSensorDialog> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
List<DeviceFunctionData> updateValuesForAddedFunctions(List<DeviceFunctionData> addedFunctions) {
|
|
||||||
|
List<DeviceFunctionData> _updateValuesForAddedFunctions(
|
||||||
|
List<DeviceFunctionData> addedFunctions,
|
||||||
|
) {
|
||||||
|
const mappableSteppedFunctions = <String>{
|
||||||
|
'static_max_dis',
|
||||||
|
'presence_reference',
|
||||||
|
'moving_reference',
|
||||||
|
'perceptual_boundary',
|
||||||
|
'moving_boundary',
|
||||||
|
'moving_rigger_time',
|
||||||
|
'moving_static_time',
|
||||||
|
'none_body_time',
|
||||||
|
'moving_max_dis',
|
||||||
|
};
|
||||||
return addedFunctions.map((function) {
|
return addedFunctions.map((function) {
|
||||||
if (function.functionCode == 'sensitivity') {
|
if (mappableSteppedFunctions.contains(function.functionCode)) {
|
||||||
return function.copyWith(
|
final mappedValue = mapSteppedValue(
|
||||||
value: function.value,
|
value: function.value,
|
||||||
|
inputStep: CpsSliderHelpers.dividendOfRange(function.functionCode),
|
||||||
|
inputRange: CpsSliderHelpers.sliderRange(function.functionCode),
|
||||||
|
outputRange: CpsSliderHelpers.mappedRange(function.functionCode),
|
||||||
|
);
|
||||||
|
return DeviceFunctionData(
|
||||||
|
value: mappedValue,
|
||||||
|
entityId: function.entityId,
|
||||||
|
functionCode: function.functionCode,
|
||||||
|
operationName: function.operationName,
|
||||||
condition: function.condition,
|
condition: function.condition,
|
||||||
|
actionExecutor: function.actionExecutor,
|
||||||
|
valueDescription: function.valueDescription,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return function;
|
return function;
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mapSteppedValue({
|
||||||
|
required (double min, double max) inputRange,
|
||||||
|
required double inputStep,
|
||||||
|
required (double min, double max, double dividend) outputRange,
|
||||||
|
required double value,
|
||||||
|
}) {
|
||||||
|
final (inputMin, inputMax) = inputRange;
|
||||||
|
final (outputMin, outputMax, outputStep) = outputRange;
|
||||||
|
|
||||||
|
final clampedValue = value.clamp(inputMin, inputMax);
|
||||||
|
|
||||||
|
final stepsFromMin = ((clampedValue - inputMin) / inputStep).round();
|
||||||
|
|
||||||
|
final mappedValue = outputMin + (stepsFromMin * outputStep);
|
||||||
|
|
||||||
|
return mappedValue.clamp(outputMin, outputMax).round();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,22 +66,4 @@ class CpsDialogSliderSelector extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
double reverseMappedValue(double value) {
|
|
||||||
final (inputMin, inputMax) =
|
|
||||||
CpsSliderHelpers.sliderRange(selectedFunctionData.functionCode);
|
|
||||||
final (outputMin, outputMax, outputStep) = CpsSliderHelpers.mappedRange(
|
|
||||||
selectedFunctionData.functionCode,
|
|
||||||
);
|
|
||||||
|
|
||||||
final clampedValue = value.clamp(outputMin, outputMax);
|
|
||||||
|
|
||||||
final stepsFromMin = ((clampedValue - outputMin) / outputStep).round();
|
|
||||||
|
|
||||||
final mappedValue = inputMin +
|
|
||||||
(stepsFromMin *
|
|
||||||
CpsSliderHelpers.dividendOfRange(selectedFunctionData.functionCode));
|
|
||||||
|
|
||||||
return mappedValue.clamp(inputMin, inputMax);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,14 @@ abstract final class CpsSliderHelpers {
|
|||||||
final defaultDivdidend = dividendOfRange(functionCode);
|
final defaultDivdidend = dividendOfRange(functionCode);
|
||||||
return switch (functionCode) {
|
return switch (functionCode) {
|
||||||
'static_max_dis' => (0, 500, 50),
|
'static_max_dis' => (0, 500, 50),
|
||||||
'presence_reference' => (0, 255, 50),
|
'presence_reference' => (0, 255, 5),
|
||||||
'moving_reference' => (0, 255, 5),
|
'moving_reference' => (0, 255, 5),
|
||||||
'perceptual_boundary' => (0, 500, 50),
|
'perceptual_boundary' => (0, 500, 50),
|
||||||
'moving_boundary' => (0, 500, 50),
|
'moving_boundary' => (0, 500, 50),
|
||||||
'moving_rigger_time' => (0, 2000, 100),
|
'moving_rigger_time' => (0, 2000, 100),
|
||||||
'moving_static_time' => (0, 6000, 100),
|
'moving_static_time' => (0, 60000, 1000),
|
||||||
'none_body_time' => (0, 300000, 500),
|
'none_body_time' => (0, 300000, 5000),
|
||||||
|
'moving_max_dis' => (0, 500, 50),
|
||||||
_ => (defaultMin, defaultMax, defaultDivdidend),
|
_ => (defaultMin, defaultMax, defaultDivdidend),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -83,4 +84,7 @@ abstract final class CpsSliderHelpers {
|
|||||||
_ => '${parsedValue?.toStringAsFixed(0) ?? 0}',
|
_ => '${parsedValue?.toStringAsFixed(0) ?? 0}',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// TODO: Sports Para causes 400 in IF and THEN / sports_para
|
||||||
|
// TODO: Detection range causes 400 in IF / moving_range
|
||||||
|
// TODO: Distance of moving objects causes 400 in IF / presence_range
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user