fixed automation and tab to run bugs

This commit is contained in:
ashraf_personal
2024-11-27 00:30:13 +03:00
parent 8d908e894b
commit 644e56aa7a
5 changed files with 374 additions and 156 deletions

View File

@ -15,9 +15,6 @@ part 'routine_state.dart';
const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6'; const spaceId = '25c96044-fadf-44bb-93c7-3c079e527ce6';
class RoutineBloc extends Bloc<RoutineEvent, RoutineState> { class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
// bool isAutomation = false;
// bool isTabToRun = false;
RoutineBloc() : super(const RoutineState()) { RoutineBloc() : super(const RoutineState()) {
on<AddToIfContainer>(_onAddToIfContainer); on<AddToIfContainer>(_onAddToIfContainer);
on<AddToThenContainer>(_onAddToThenContainer); on<AddToThenContainer>(_onAddToThenContainer);
@ -159,50 +156,54 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
emit(state.copyWith(isLoading: true)); emit(state.copyWith(isLoading: true));
final actions = state.thenItems final actions = state.thenItems.expand((item) {
.map((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
final functions = return functions.map((function) {
state.selectedFunctions[item['uniqueCustomId']] ?? []; if (function.functionCode == 'automation') {
if (functions.isEmpty) return null;
final function = functions.first;
if (item['deviceId'] == 'delay') {
return CreateSceneAction(
entityId: function.entityId,
actionExecutor: 'delay',
executorProperty: CreateSceneExecutorProperty(
functionCode: '',
functionValue: '',
delaySeconds: function.value,
),
);
}
return CreateSceneAction( return CreateSceneAction(
entityId: function.entityId, entityId: function.entityId,
actionExecutor: 'device_issue', actionExecutor: function.value,
executorProperty: null,
);
}
if (item['deviceId'] == 'delay') {
return CreateSceneAction(
entityId: function.entityId,
actionExecutor: 'delay',
executorProperty: CreateSceneExecutorProperty( executorProperty: CreateSceneExecutorProperty(
functionCode: function.functionCode.toString(), functionCode: '',
functionValue: function.value, functionValue: '',
delaySeconds: 0, delaySeconds: int.tryParse(function.value.toString()) ?? 0,
), ),
); );
}) }
.whereType<CreateSceneAction>()
.toList(); return CreateSceneAction(
entityId: function.entityId,
actionExecutor: 'device_issue',
executorProperty: CreateSceneExecutorProperty(
functionCode: function.functionCode,
functionValue: function.value,
delaySeconds: 0,
),
);
});
}).toList();
final createSceneModel = CreateSceneModel( final createSceneModel = CreateSceneModel(
spaceUuid: spaceId, spaceUuid: spaceId,
iconId: state.selectedIcon ?? '', iconId: state.selectedIcon ?? '',
showInDevice: true, showInDevice: true,
sceneName: state.routineName ?? '', sceneName: state.routineName!,
decisionExpr: 'and', decisionExpr: 'and',
actions: actions, actions: actions,
); );
final result = await SceneApi.createScene(createSceneModel); final result = await SceneApi.createScene(createSceneModel);
if (result['success']) { if (result['success']) {
emit(const RoutineState()); emit(_resetState());
add(const LoadScenes(spaceId));
} else { } else {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
@ -212,7 +213,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} catch (e) { } catch (e) {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
errorMessage: e.toString(), errorMessage: 'Something went wrong',
)); ));
} }
} }
@ -229,26 +230,24 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
emit(state.copyWith(isLoading: true)); emit(state.copyWith(isLoading: true));
final conditions = state.ifItems final conditions = state.ifItems.expand((item) {
.map((item) { final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
final functions = return functions.map((function) {
state.selectedFunctions[item['uniqueCustomId']] ?? []; return Condition(
if (functions.isEmpty) return null; code: state.selectedFunctions[item['uniqueCustomId']]!.indexOf(
function,
final function = functions.first; ) +
return CreateCondition( 1,
code: state.ifItems.indexOf(item) + 1, entityId: function.entityId,
entityId: function.entityId, entityType: 'device_report',
entityType: 'device_report', expr: ConditionExpr(
expr: ConditionExpr( statusCode: function.functionCode,
statusCode: function.functionCode, comparator: function.condition ?? '==',
comparator: function.condition ?? '==', statusValue: function.value,
statusValue: function.value, ),
), );
); });
}) }).toList();
.whereType<CreateCondition>()
.toList();
if (conditions.isEmpty) { if (conditions.isEmpty) {
emit(state.copyWith( emit(state.copyWith(
@ -258,61 +257,54 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
return; return;
} }
final actions = state.thenItems.expand((item) {
final functions = state.selectedFunctions[item['uniqueCustomId']] ?? [];
return functions.map((function) {
if (function.functionCode == 'automation') {
return AutomationAction(
entityId: function.entityId,
actionExecutor: function.value,
);
}
if (item['deviceId'] == 'delay') {
return AutomationAction(
entityId: function.entityId,
actionExecutor: 'delay',
executorProperty: ExecutorProperty(
delaySeconds: int.tryParse(function.value.toString()) ?? 0,
),
);
}
return AutomationAction(
entityId: function.entityId,
actionExecutor: 'device_issue',
executorProperty: ExecutorProperty(
functionCode: function.functionCode,
functionValue: function.value,
),
);
});
}).toList();
final createAutomationModel = CreateAutomationModel( final createAutomationModel = CreateAutomationModel(
unitUuid: spaceId, spaceUuid: spaceId,
automationName: state.routineName!, automationName: state.routineName!,
decisionExpr: state.selectedAutomationOperator, decisionExpr: state.selectedAutomationOperator,
effectiveTime: state.effectiveTime ?? effectiveTime: EffectiveTime(
EffectiveTime( start: state.effectiveTime?.start ?? '00:00',
start: '00:00', end: state.effectiveTime?.end ?? '23:59',
end: '23:59', loops: state.effectiveTime?.loops ?? '1111111',
loops: '1111111', ),
),
conditions: conditions, conditions: conditions,
actions: state.thenItems actions: actions,
.map((item) {
final functions =
state.selectedFunctions[item['uniqueCustomId']] ?? [];
if (functions.isEmpty) return null;
final function = functions.first;
if (function.functionCode == 'automation') {
return CreateSceneAction(
entityId: function.entityId,
actionExecutor: function.value,
executorProperty: null,
);
}
if (item['deviceId'] == 'delay') {
return CreateSceneAction(
entityId: function.entityId,
actionExecutor: 'delay',
executorProperty: CreateSceneExecutorProperty(
functionCode: '',
functionValue: '',
delaySeconds: function.value,
),
);
}
return CreateSceneAction(
entityId: function.entityId,
actionExecutor: 'device_issue',
executorProperty: CreateSceneExecutorProperty(
functionCode: function.functionCode,
functionValue: function.value,
delaySeconds: 0,
),
);
})
.whereType<CreateSceneAction>()
.toList(),
); );
final result = await SceneApi.createAutomation(createAutomationModel); final result = await SceneApi.createAutomation(createAutomationModel);
if (result['success']) { if (result['success']) {
emit(const RoutineState()); emit(_resetState());
add(const LoadAutomation(spaceId));
} else { } else {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
@ -322,7 +314,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
} catch (e) { } catch (e) {
emit(state.copyWith( emit(state.copyWith(
isLoading: false, isLoading: false,
errorMessage: e.toString(), errorMessage: 'Something went wrong',
)); ));
} }
} }
@ -349,6 +341,7 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
FutureOr<void> _onEffectiveTimeEvent( FutureOr<void> _onEffectiveTimeEvent(
EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) { EffectiveTimePeriodEvent event, Emitter<RoutineState> emit) {
debugPrint(event.effectiveTime.toString());
emit(state.copyWith(effectiveTime: event.effectiveTime)); emit(state.copyWith(effectiveTime: event.effectiveTime));
} }
@ -356,4 +349,25 @@ class RoutineBloc extends Bloc<RoutineEvent, RoutineState> {
SetRoutineName event, Emitter<RoutineState> emit) { SetRoutineName event, Emitter<RoutineState> emit) {
emit(state.copyWith(routineName: event.name)); emit(state.copyWith(routineName: event.name));
} }
RoutineState _resetState() {
return const RoutineState(
ifItems: [],
thenItems: [],
selectedFunctions: {},
scenes: [],
automations: [],
isLoading: false,
errorMessage: null,
loadScenesErrorMessage: null,
loadAutomationErrorMessage: null,
searchText: '',
selectedIcon: null,
isTabToRun: false,
isAutomation: false,
selectedAutomationOperator: 'AND',
effectiveTime: null,
routineName: null,
);
}
} }

View File

@ -142,9 +142,16 @@ class SaveRoutineHelper {
DialogFooter( DialogFooter(
onCancel: () => Navigator.pop(context), onCancel: () => Navigator.pop(context),
onConfirm: () { onConfirm: () {
context if (state.isAutomation) {
.read<RoutineBloc>() context
.add(const CreateSceneEvent()); .read<RoutineBloc>()
.add(const CreateAutomationEvent());
} else {
context
.read<RoutineBloc>()
.add(const CreateSceneEvent());
}
Navigator.pop(context); Navigator.pop(context);
}, },
isConfirmEnabled: true, isConfirmEnabled: true,

View File

@ -1,18 +1,187 @@
import 'dart:convert'; import 'dart:convert';
import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart'; import 'package:syncrow_web/pages/routiens/models/create_scene_and_autoamtion/create_scene_model.dart';
// class CreateAutomationModel {
// String unitUuid;
// String automationName;
// String decisionExpr;
// EffectiveTime effectiveTime;
// List<CreateCondition> conditions;
// List<CreateSceneAction> actions;
// CreateAutomationModel({
// required this.unitUuid,
// required this.automationName,
// required this.decisionExpr,
// required this.effectiveTime,
// required this.conditions,
// required this.actions,
// });
// CreateAutomationModel copyWith({
// String? unitUuid,
// String? automationName,
// String? decisionExpr,
// EffectiveTime? effectiveTime,
// List<CreateCondition>? conditions,
// List<CreateSceneAction>? actions,
// }) {
// return CreateAutomationModel(
// unitUuid: unitUuid ?? this.unitUuid,
// automationName: automationName ?? this.automationName,
// decisionExpr: decisionExpr ?? this.decisionExpr,
// effectiveTime: effectiveTime ?? this.effectiveTime,
// conditions: conditions ?? this.conditions,
// actions: actions ?? this.actions,
// );
// }
// Map<String, dynamic> toMap([String? automationId]) {
// return {
// if (automationId == null) 'spaceUuid': unitUuid,
// 'automationName': automationName,
// 'decisionExpr': decisionExpr,
// 'effectiveTime': effectiveTime.toMap(),
// 'conditions': conditions.map((x) => x.toMap()).toList(),
// 'actions': actions.map((x) => x.toMap()).toList(),
// };
// }
// factory CreateAutomationModel.fromMap(Map<String, dynamic> map) {
// return CreateAutomationModel(
// unitUuid: map['spaceUuid'] ?? '',
// automationName: map['automationName'] ?? '',
// decisionExpr: map['decisionExpr'] ?? '',
// effectiveTime: EffectiveTime.fromMap(map['effectiveTime']),
// conditions: List<CreateCondition>.from(
// map['conditions']?.map((x) => CreateCondition.fromMap(x))),
// actions: List<CreateSceneAction>.from(
// map['actions']?.map((x) => CreateSceneAction.fromMap(x))),
// );
// }
// String toJson([String? automationId]) => json.encode(toMap(automationId));
// factory CreateAutomationModel.fromJson(String source) =>
// CreateAutomationModel.fromMap(json.decode(source));
// @override
// String toString() {
// return 'CreateAutomationModel(unitUuid: $unitUuid, automationName: $automationName, decisionExpr: $decisionExpr, effectiveTime: $effectiveTime, conditions: $conditions, actions: $actions)';
// }
// }
// class EffectiveTime {
// String start;
// String end;
// String loops;
// EffectiveTime({
// required this.start,
// required this.end,
// required this.loops,
// });
// Map<String, dynamic> toMap() {
// return {
// 'start': start,
// 'end': end,
// 'loops': loops,
// };
// }
// factory EffectiveTime.fromMap(Map<String, dynamic> map) {
// return EffectiveTime(
// start: map['start'] ?? '',
// end: map['end'] ?? '',
// loops: map['loops'] ?? '',
// );
// }
// @override
// String toString() => 'EffectiveTime(start: $start, end: $end, loops: $loops)';
// }
// class CreateCondition {
// int code;
// String entityId;
// String entityType;
// ConditionExpr expr;
// CreateCondition({
// required this.code,
// required this.entityId,
// required this.entityType,
// required this.expr,
// });
// Map<String, dynamic> toMap() {
// return {
// 'code': code,
// 'entityId': entityId,
// 'entityType': entityType,
// 'expr': expr.toMap(),
// };
// }
// factory CreateCondition.fromMap(Map<String, dynamic> map) {
// return CreateCondition(
// code: map['code'] ?? 0,
// entityId: map['entityId'] ?? '',
// entityType: map['entityType'] ?? '',
// expr: ConditionExpr.fromMap(map['expr']),
// );
// }
// @override
// String toString() =>
// 'CreateCondition(code: $code, entityId: $entityId, entityType: $entityType, expr: $expr)';
// }
// class ConditionExpr {
// String statusCode;
// String comparator;
// dynamic statusValue;
// ConditionExpr({
// required this.statusCode,
// required this.comparator,
// required this.statusValue,
// });
// Map<String, dynamic> toMap() {
// return {
// 'statusCode': statusCode,
// 'comparator': comparator,
// 'statusValue': statusValue,
// };
// }
// factory ConditionExpr.fromMap(Map<String, dynamic> map) {
// return ConditionExpr(
// statusCode: map['statusCode'] ?? '',
// comparator: map['comparator'] ?? '',
// statusValue: map['statusValue'],
// );
// }
// @override
// String toString() =>
// 'ConditionExpr(statusCode: $statusCode, comparator: $comparator, statusValue: $statusValue)';
// }
import 'dart:convert';
class CreateAutomationModel { class CreateAutomationModel {
String unitUuid; String spaceUuid;
String automationName; String automationName;
String decisionExpr; String decisionExpr;
EffectiveTime effectiveTime; EffectiveTime effectiveTime;
List<CreateCondition> conditions; List<Condition> conditions;
List<CreateSceneAction> actions; List<AutomationAction> actions;
CreateAutomationModel({ CreateAutomationModel({
required this.unitUuid, required this.spaceUuid,
required this.automationName, required this.automationName,
required this.decisionExpr, required this.decisionExpr,
required this.effectiveTime, required this.effectiveTime,
@ -20,27 +189,9 @@ class CreateAutomationModel {
required this.actions, required this.actions,
}); });
CreateAutomationModel copyWith({ Map<String, dynamic> toMap() {
String? unitUuid,
String? automationName,
String? decisionExpr,
EffectiveTime? effectiveTime,
List<CreateCondition>? conditions,
List<CreateSceneAction>? actions,
}) {
return CreateAutomationModel(
unitUuid: unitUuid ?? this.unitUuid,
automationName: automationName ?? this.automationName,
decisionExpr: decisionExpr ?? this.decisionExpr,
effectiveTime: effectiveTime ?? this.effectiveTime,
conditions: conditions ?? this.conditions,
actions: actions ?? this.actions,
);
}
Map<String, dynamic> toMap([String? automationId]) {
return { return {
if (automationId == null) 'spaceUuid': unitUuid, 'spaceUuid': spaceUuid,
'automationName': automationName, 'automationName': automationName,
'decisionExpr': decisionExpr, 'decisionExpr': decisionExpr,
'effectiveTime': effectiveTime.toMap(), 'effectiveTime': effectiveTime.toMap(),
@ -51,26 +202,21 @@ class CreateAutomationModel {
factory CreateAutomationModel.fromMap(Map<String, dynamic> map) { factory CreateAutomationModel.fromMap(Map<String, dynamic> map) {
return CreateAutomationModel( return CreateAutomationModel(
unitUuid: map['spaceUuid'] ?? '', spaceUuid: map['spaceUuid'] ?? '',
automationName: map['automationName'] ?? '', automationName: map['automationName'] ?? '',
decisionExpr: map['decisionExpr'] ?? '', decisionExpr: map['decisionExpr'] ?? '',
effectiveTime: EffectiveTime.fromMap(map['effectiveTime']), effectiveTime: EffectiveTime.fromMap(map['effectiveTime']),
conditions: List<CreateCondition>.from( conditions: List<Condition>.from(
map['conditions']?.map((x) => CreateCondition.fromMap(x))), map['conditions']?.map((x) => Condition.fromMap(x)) ?? []),
actions: List<CreateSceneAction>.from( actions: List<AutomationAction>.from(
map['actions']?.map((x) => CreateSceneAction.fromMap(x))), map['actions']?.map((x) => AutomationAction.fromMap(x)) ?? []),
); );
} }
String toJson([String? automationId]) => json.encode(toMap(automationId)); String toJson() => json.encode(toMap());
factory CreateAutomationModel.fromJson(String source) => factory CreateAutomationModel.fromJson(String source) =>
CreateAutomationModel.fromMap(json.decode(source)); CreateAutomationModel.fromMap(json.decode(source));
@override
String toString() {
return 'CreateAutomationModel(unitUuid: $unitUuid, automationName: $automationName, decisionExpr: $decisionExpr, effectiveTime: $effectiveTime, conditions: $conditions, actions: $actions)';
}
} }
class EffectiveTime { class EffectiveTime {
@ -99,18 +245,15 @@ class EffectiveTime {
loops: map['loops'] ?? '', loops: map['loops'] ?? '',
); );
} }
@override
String toString() => 'EffectiveTime(start: $start, end: $end, loops: $loops)';
} }
class CreateCondition { class Condition {
int code; int code;
String entityId; String entityId;
String entityType; String entityType;
ConditionExpr expr; ConditionExpr expr;
CreateCondition({ Condition({
required this.code, required this.code,
required this.entityId, required this.entityId,
required this.entityType, required this.entityType,
@ -126,18 +269,14 @@ class CreateCondition {
}; };
} }
factory CreateCondition.fromMap(Map<String, dynamic> map) { factory Condition.fromMap(Map<String, dynamic> map) {
return CreateCondition( return Condition(
code: map['code'] ?? 0, code: map['code']?.toInt() ?? 0,
entityId: map['entityId'] ?? '', entityId: map['entityId'] ?? '',
entityType: map['entityType'] ?? '', entityType: map['entityType'] ?? '',
expr: ConditionExpr.fromMap(map['expr']), expr: ConditionExpr.fromMap(map['expr']),
); );
} }
@override
String toString() =>
'CreateCondition(code: $code, entityId: $entityId, entityType: $entityType, expr: $expr)';
} }
class ConditionExpr { class ConditionExpr {
@ -166,8 +305,62 @@ class ConditionExpr {
statusValue: map['statusValue'], statusValue: map['statusValue'],
); );
} }
}
@override
String toString() => class AutomationAction {
'ConditionExpr(statusCode: $statusCode, comparator: $comparator, statusValue: $statusValue)'; String entityId;
String actionExecutor;
ExecutorProperty? executorProperty;
AutomationAction({
required this.entityId,
required this.actionExecutor,
this.executorProperty,
});
Map<String, dynamic> toMap() {
return {
'entityId': entityId,
'actionExecutor': actionExecutor,
'executorProperty': executorProperty?.toMap(),
};
}
factory AutomationAction.fromMap(Map<String, dynamic> map) {
return AutomationAction(
entityId: map['entityId'] ?? '',
actionExecutor: map['actionExecutor'] ?? '',
executorProperty: map['executorProperty'] != null
? ExecutorProperty.fromMap(map['executorProperty'])
: null,
);
}
}
class ExecutorProperty {
String? functionCode;
dynamic functionValue;
int? delaySeconds;
ExecutorProperty({
this.functionCode,
this.functionValue,
this.delaySeconds,
});
Map<String, dynamic> toMap() {
return {
if (functionCode != null) 'functionCode': functionCode,
if (functionValue != null) 'functionValue': functionValue,
if (delaySeconds != null) 'delaySeconds': delaySeconds,
};
}
factory ExecutorProperty.fromMap(Map<String, dynamic> map) {
return ExecutorProperty(
functionCode: map['functionCode'],
functionValue: map['functionValue'],
delaySeconds: map['delaySeconds']?.toInt(),
);
}
} }

View File

@ -74,7 +74,7 @@ class _AutomationDialogState extends State<AutomationDialog> {
DeviceFunctionData( DeviceFunctionData(
entityId: widget.automationId, entityId: widget.automationId,
functionCode: 'automation', functionCode: 'automation',
value: _isEnabled, value: _isEnabled ? 'rule_enable' : 'rule_disable',
operationName: 'Automation', operationName: 'Automation',
), ),
], ],

View File

@ -29,11 +29,13 @@ class SceneApi {
rethrow; rethrow;
} }
} }
// //
// create automation // create automation
static Future<Map<String, dynamic>> createAutomation( static Future<Map<String, dynamic>> createAutomation(
CreateAutomationModel createAutomationModel) async { CreateAutomationModel createAutomationModel) async {
try { try {
debugPrint("automation body ${createAutomationModel.toMap()}");
final response = await _httpService.post( final response = await _httpService.post(
path: ApiEndpoints.createAutomation, path: ApiEndpoints.createAutomation,
body: createAutomationModel.toMap(), body: createAutomationModel.toMap(),
@ -42,8 +44,10 @@ class SceneApi {
return json; return json;
}, },
); );
debugPrint('create automation response: $response');
return response; return response;
} catch (e) { } catch (e) {
debugPrint(e.toString());
rethrow; rethrow;
} }
} }