mirror of https://github.com/nymea/nymea.git
Add support for state based rule action params
parent
87595faf6d
commit
774452ff7c
|
|
@ -188,6 +188,8 @@ void JsonTypes::init()
|
|||
s_ruleActionParam.insert("o:value", basicTypeRef());
|
||||
s_ruleActionParam.insert("o:eventTypeId", basicTypeToString(Uuid));
|
||||
s_ruleActionParam.insert("o:eventParamTypeId", basicTypeToString(Uuid));
|
||||
s_ruleActionParam.insert("o:deviceId", basicTypeToString(Uuid));
|
||||
s_ruleActionParam.insert("o:stateTypeId", basicTypeToString(Uuid));
|
||||
|
||||
// ParamDescriptor
|
||||
s_paramDescriptor.insert("o:paramTypeId", basicTypeToString(Uuid));
|
||||
|
|
@ -612,10 +614,13 @@ QVariantMap JsonTypes::packRuleActionParam(const RuleActionParam &ruleActionPara
|
|||
} else {
|
||||
variantMap.insert("paramName", ruleActionParam.paramName());
|
||||
}
|
||||
// if this ruleaction param has a valid EventTypeId, there is no value
|
||||
if (ruleActionParam.eventTypeId() != EventTypeId()) {
|
||||
|
||||
if (ruleActionParam.isEventBased()) {
|
||||
variantMap.insert("eventTypeId", ruleActionParam.eventTypeId().toString());
|
||||
variantMap.insert("eventParamTypeId", ruleActionParam.eventParamTypeId().toString());
|
||||
} else if (ruleActionParam.isStateBased()) {
|
||||
variantMap.insert("deviceId", ruleActionParam.deviceId().toString());
|
||||
variantMap.insert("stateTypeId", ruleActionParam.stateTypeId().toString());
|
||||
} else {
|
||||
variantMap.insert("value", ruleActionParam.value());
|
||||
}
|
||||
|
|
@ -1429,13 +1434,19 @@ RuleActionParam JsonTypes::unpackRuleActionParam(const QVariantMap &ruleActionPa
|
|||
|
||||
ParamTypeId paramTypeId = ParamTypeId(ruleActionParamMap.value("paramTypeId").toString());
|
||||
QString paramName = ruleActionParamMap.value("paramName").toString();
|
||||
QVariant value = ruleActionParamMap.value("value");
|
||||
EventTypeId eventTypeId = EventTypeId(ruleActionParamMap.value("eventTypeId").toString());
|
||||
ParamTypeId eventParamTypeId = ParamTypeId(ruleActionParamMap.value("eventParamTypeId").toString());
|
||||
|
||||
RuleActionParam param;
|
||||
if (paramTypeId.isNull()) {
|
||||
return RuleActionParam(paramName, value, eventTypeId, eventParamTypeId);
|
||||
param = RuleActionParam(paramName);
|
||||
} else {
|
||||
param = RuleActionParam(paramTypeId);
|
||||
}
|
||||
return RuleActionParam(paramTypeId, value, eventTypeId, eventParamTypeId);
|
||||
param.setValue(ruleActionParamMap.value("value"));
|
||||
param.setEventTypeId(EventTypeId(ruleActionParamMap.value("eventTypeId").toString()));
|
||||
param.setEventParamTypeId(ParamTypeId(ruleActionParamMap.value("eventParamTypeId").toString()));
|
||||
param.setDeviceId(DeviceId(ruleActionParamMap.value("deviceId").toString()));
|
||||
param.setStateTypeId(StateTypeId(ruleActionParamMap.value("stateTypeId").toString()));
|
||||
return param;
|
||||
}
|
||||
|
||||
/*! Returns a \l{RuleActionParamList} created from the given \a ruleActionParamList. */
|
||||
|
|
|
|||
|
|
@ -438,31 +438,85 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
|||
QList<Action> actions;
|
||||
foreach (const RuleAction &ruleAction, ruleActions) {
|
||||
if (ruleAction.type() == RuleAction::TypeDevice) {
|
||||
actions.append(ruleAction.toAction());
|
||||
Device *device = m_deviceManager->findConfiguredDevice(ruleAction.deviceId());
|
||||
ActionTypeId actionTypeId = ruleAction.actionTypeId();
|
||||
ParamList params;
|
||||
bool ok = true;
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) {
|
||||
if (ruleActionParam.isValueBased()) {
|
||||
params.append(Param(ruleActionParam.paramTypeId(), ruleActionParam.value()));
|
||||
} else if (ruleActionParam.isStateBased()) {
|
||||
Device *stateDevice = m_deviceManager->findConfiguredDevice(ruleActionParam.deviceId());
|
||||
if (!stateDevice) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot find device" << ruleActionParam.deviceId() << "required by rule action" << ruleAction.id();
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
DeviceClass stateDeviceClass = m_deviceManager->findDeviceClass(stateDevice->deviceClassId());
|
||||
if (!stateDeviceClass.hasStateType(ruleActionParam.stateTypeId())) {
|
||||
qCWarning(dcRuleEngine()) << "Device" << device->name() << device->id() << "does not have a state type" << ruleActionParam.stateTypeId();
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
params.append(Param(ruleActionParam.paramTypeId(), stateDevice->stateValue(ruleActionParam.stateTypeId())));
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
qCWarning(dcRuleEngine()) << "Not executing rule action" << ruleAction.id();
|
||||
continue;
|
||||
}
|
||||
Action action(actionTypeId, device->id());
|
||||
action.setParams(params);
|
||||
actions.append(action);
|
||||
} else {
|
||||
QList<Device*> devices = m_deviceManager->findConfiguredDevices(ruleAction.interface());
|
||||
foreach (Device* device, devices) {
|
||||
DeviceClass dc = m_deviceManager->findDeviceClass(device->deviceClassId());
|
||||
ActionType at = dc.actionTypes().findByName(ruleAction.interfaceAction());
|
||||
if (at.id().isNull()) {
|
||||
DeviceClass deviceClass = m_deviceManager->findDeviceClass(device->deviceClassId());
|
||||
ActionType actionType = deviceClass.actionTypes().findByName(ruleAction.interfaceAction());
|
||||
if (actionType.id().isNull()) {
|
||||
qCWarning(dcRuleEngine()) << "Error creating Action. The given DeviceClass does not implement action:" << ruleAction.interfaceAction();
|
||||
continue;
|
||||
}
|
||||
Action action = Action(at.id(), device->id());
|
||||
|
||||
ParamList params;
|
||||
foreach (const RuleActionParam &rap, ruleAction.ruleActionParams()) {
|
||||
ParamType pt = at.paramTypes().findByName(rap.paramName());
|
||||
if (pt.id().isNull()) {
|
||||
qCWarning(dcRuleEngine()) << "Error creating Action. Failed to match interface param type to DeviceClass paramtype.";
|
||||
bool ok = true;
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) {
|
||||
ParamType paramType = actionType.paramTypes().findByName(ruleActionParam.paramName());
|
||||
if (paramType.id().isNull()) {
|
||||
qCWarning(dcRuleEngine()) << "Error creating Action. The given ActionType does not have a parameter:" << ruleActionParam.paramName();
|
||||
ok = false;
|
||||
continue;
|
||||
}
|
||||
params.append(Param(pt.id(), rap.value()));
|
||||
if (ruleActionParam.isValueBased()) {
|
||||
params.append(Param(paramType.id(), ruleActionParam.value()));
|
||||
} else if (ruleActionParam.isStateBased()) {
|
||||
Device *stateDevice = m_deviceManager->findConfiguredDevice(ruleActionParam.deviceId());
|
||||
if (!stateDevice) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot find device" << ruleActionParam.deviceId() << "required by rule action" << ruleAction.id();
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
DeviceClass stateDeviceClass = m_deviceManager->findDeviceClass(stateDevice->deviceClassId());
|
||||
if (!stateDeviceClass.hasStateType(ruleActionParam.stateTypeId())) {
|
||||
qCWarning(dcRuleEngine()) << "Device" << device->name() << device->id() << "does not have a state type" << ruleActionParam.stateTypeId();
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
params.append(Param(paramType.id(), stateDevice->stateValue(ruleActionParam.stateTypeId())));
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
qCWarning(dcRuleEngine()) << "Not executing rule action" << ruleAction.id();
|
||||
continue;
|
||||
}
|
||||
|
||||
Action action = Action(actionType.id(), device->id());
|
||||
action.setParams(params);
|
||||
actions.append(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const Action &action, actions) {
|
||||
qCDebug(dcRuleEngine) << "Executing action" << action.actionTypeId() << action.params();
|
||||
DeviceManager::DeviceError status = executeAction(action);
|
||||
|
|
@ -652,9 +706,7 @@ void NymeaCore::gotEvent(const Event &event)
|
|||
foreach (RuleActionParam ruleActionParam, ruleAction.ruleActionParams()) {
|
||||
// if this event param should be taken over in this action
|
||||
if (event.eventTypeId() == ruleActionParam.eventTypeId()) {
|
||||
QVariant eventValue = event.params().first().value();
|
||||
|
||||
// TODO: get param names...when an event has more than one parameter
|
||||
QVariant eventValue = event.params().paramValue(ruleActionParam.eventParamTypeId());
|
||||
|
||||
// TODO: limits / scale calculation -> actionValue = eventValue * x
|
||||
// something like a EventParamDescriptor
|
||||
|
|
|
|||
|
|
@ -401,55 +401,6 @@ RuleEngine::RuleError RuleEngine::addRule(const Rule &rule, bool fromEdit)
|
|||
return RuleErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
// check possible eventTypeIds in params
|
||||
if (action.isEventBased()) {
|
||||
foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) {
|
||||
if (ruleActionParam.eventTypeId() != EventTypeId()) {
|
||||
// We have an eventTypeId
|
||||
if (rule.eventDescriptors().isEmpty()) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. RuleAction" << action.actionTypeId() << "contains an eventTypeId, but there are no eventDescriptors.";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
|
||||
// now check if this eventType is in the eventDescriptorList of this rule
|
||||
if (!checkEventDescriptors(rule.eventDescriptors(), ruleActionParam.eventTypeId())) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. EventTypeId from RuleAction" << action.actionTypeId() << "not in eventDescriptors.";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
|
||||
// check if the param type of the event and the action match
|
||||
QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamTypeId());
|
||||
QVariant v(eventParamType);
|
||||
QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.paramTypeId());
|
||||
if (eventParamType != actionParamType && !v.canConvert(actionParamType)) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given event param " << ruleActionParam.eventParamTypeId().toString() << "have not the same type:";
|
||||
qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType;
|
||||
qCWarning(dcRuleEngine) << " -> eventParamType:" << eventParamType;
|
||||
return RuleErrorTypesNotMatching;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// verify action params
|
||||
foreach (const ActionType &actionType, deviceClass.actionTypes()) {
|
||||
if (actionType.id() == action.actionTypeId()) {
|
||||
ParamList finalParams = action.toAction().params();
|
||||
DeviceManager::DeviceError paramCheck = NymeaCore::instance()->deviceManager()->verifyParams(actionType.paramTypes(), finalParams);
|
||||
if (paramCheck != DeviceManager::DeviceErrorNoError) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Got an invalid actionParam.";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) {
|
||||
if (!ruleActionParam.isValid()) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Got an actionParam with \"value\" AND \"eventTypeId\".";
|
||||
return RuleEngine::RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
|
||||
} else { // Is TypeInterface
|
||||
Interface iface = NymeaCore::instance()->deviceManager()->supportedInterfaces().findByName(action.interface());
|
||||
if (!iface.isValid()) {
|
||||
|
|
@ -471,77 +422,145 @@ RuleEngine::RuleError RuleEngine::addRule(const Rule &rule, bool fromEdit)
|
|||
return RuleError::RuleErrorInvalidParameter;
|
||||
}
|
||||
}
|
||||
// TODO: Check params
|
||||
}
|
||||
|
||||
foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) {
|
||||
if (ruleActionParam.isEventBased()) {
|
||||
// We have an eventTypeId, see if the rule actually has such a event
|
||||
if (rule.eventDescriptors().isEmpty() || !checkEventDescriptors(rule.eventDescriptors(), ruleActionParam.eventTypeId())) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. EventTypeId from RuleAction" << action.actionTypeId() << "not in eventDescriptors.";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
|
||||
// check if the param type of the event and the action match
|
||||
QVariant::Type eventParamType = getEventParamType(ruleActionParam.eventTypeId(), ruleActionParam.eventParamTypeId());
|
||||
QVariant v(eventParamType);
|
||||
QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.paramTypeId());
|
||||
if (eventParamType != actionParamType && !v.canConvert(static_cast<int>(actionParamType))) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given event param " << ruleActionParam.eventParamTypeId().toString() << "have not the same type:";
|
||||
qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType;
|
||||
qCWarning(dcRuleEngine) << " -> eventParamType:" << eventParamType;
|
||||
return RuleErrorTypesNotMatching;
|
||||
}
|
||||
} else if (ruleActionParam.isStateBased()) {
|
||||
Device *d = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleActionParam.deviceId());
|
||||
if (!d) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create Rule. DeviceId from RuleAction" << action.actionTypeId() << "not found in system.";
|
||||
return RuleErrorDeviceNotFound;
|
||||
}
|
||||
DeviceClass stateDeviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(d->deviceClassId());
|
||||
StateType stateType = stateDeviceClass.stateTypes().findById(ruleActionParam.stateTypeId());
|
||||
QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.paramTypeId());
|
||||
QVariant v(stateType.type());
|
||||
if (actionParamType != stateType.type() && !v.canConvert(static_cast<int>(actionParamType))) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given state based param " << ruleActionParam.stateTypeId().toString() << "have not the same type:";
|
||||
qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType;
|
||||
qCWarning(dcRuleEngine) << " -> stateType:" << stateType.type();
|
||||
return RuleErrorTypesNotMatching;
|
||||
}
|
||||
} else {
|
||||
if (ruleActionParam.value().isNull()) {
|
||||
qCDebug(dcRuleEngine()) << "Cannot create rule. No param value given for action:" << ruleActionParam.paramTypeId().toString();
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
QVariant::Type actionParamType = getActionParamType(action.actionTypeId(), ruleActionParam.paramTypeId());
|
||||
if (ruleActionParam.value().type() != actionParamType && !ruleActionParam.value().canConvert(static_cast<int>(actionParamType))) {
|
||||
qCDebug(dcRuleEngine()) << "Cannot create rule. Given param value for action" << ruleActionParam.paramTypeId().toString() << "does not match type";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const RuleActionParam &ruleActionParam, action.ruleActionParams()) {
|
||||
if (!ruleActionParam.isValid()) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. There must be only one out of \"value\", \"eventTypeId/eventParamTypeID\" or \"deviceId/stateTypeId\".";
|
||||
return RuleEngine::RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check exit actions
|
||||
foreach (const RuleAction &ruleAction, rule.exitActions()) {
|
||||
if (!ruleAction.isValid()) {
|
||||
foreach (const RuleAction &ruleExitAction, rule.exitActions()) {
|
||||
if (!ruleExitAction.isValid()) {
|
||||
qWarning(dcRuleEngine()) << "Exit Action is incomplete. It must have either actionTypeId and deviceId, or interface and interfaceAction";
|
||||
return RuleErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
if (ruleAction.type() == RuleAction::TypeDevice) {
|
||||
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleAction.deviceId());
|
||||
if (ruleExitAction.type() == RuleAction::TypeDevice) {
|
||||
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleExitAction.deviceId());
|
||||
if (!device) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for exit action with actionTypeId" << ruleAction.actionTypeId();
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. No configured device for exit action with actionTypeId" << ruleExitAction.actionTypeId();
|
||||
return RuleErrorDeviceNotFound;
|
||||
}
|
||||
|
||||
DeviceClass deviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId());
|
||||
if (!deviceClass.hasActionType(ruleAction.actionTypeId())) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Device " + device->name() + " has no action type:" << ruleAction.actionTypeId();
|
||||
if (!deviceClass.hasActionType(ruleExitAction.actionTypeId())) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Device " + device->name() + " has no action type:" << ruleExitAction.actionTypeId();
|
||||
return RuleErrorActionTypeNotFound;
|
||||
}
|
||||
|
||||
// verify action params
|
||||
foreach (const ActionType &actionType, deviceClass.actionTypes()) {
|
||||
if (actionType.id() == ruleAction.actionTypeId()) {
|
||||
ParamList finalParams = ruleAction.toAction().params();
|
||||
DeviceManager::DeviceError paramCheck = NymeaCore::instance()->deviceManager()->verifyParams(actionType.paramTypes(), finalParams);
|
||||
if (paramCheck != DeviceManager::DeviceErrorNoError) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Got an invalid exit actionParam.";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit action can never be event based.
|
||||
if (ruleAction.isEventBased()) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Got exitAction with an actionParam containing an eventTypeId. ";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleAction.ruleActionParams()) {
|
||||
if (!ruleActionParam.isValid()) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Got an actionParam with \"value\" AND \"eventTypeId\".";
|
||||
return RuleEngine::RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
|
||||
} else { // Is TypeInterface
|
||||
Interface iface = NymeaCore::instance()->deviceManager()->supportedInterfaces().findByName(ruleAction.interface());
|
||||
Interface iface = NymeaCore::instance()->deviceManager()->supportedInterfaces().findByName(ruleExitAction.interface());
|
||||
if (!iface.isValid()) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. No such interface:" << ruleAction.interface();
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. No such interface:" << ruleExitAction.interface();
|
||||
return RuleError::RuleErrorInterfaceNotFound;
|
||||
}
|
||||
ActionType ifaceActionType = iface.actionTypes().findByName(ruleAction.interfaceAction());
|
||||
ActionType ifaceActionType = iface.actionTypes().findByName(ruleExitAction.interfaceAction());
|
||||
if (ifaceActionType.name().isEmpty()) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface" << iface.name() << "does not implement action" << ruleAction.interfaceAction();
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface" << iface.name() << "does not implement action" << ruleExitAction.interfaceAction();
|
||||
return RuleError::RuleErrorActionTypeNotFound;
|
||||
}
|
||||
foreach (const ParamType &ifaceActionParamType, ifaceActionType.paramTypes()) {
|
||||
if (!ruleAction.ruleActionParams().hasParam(ifaceActionParamType.name())) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action" << iface.name() << ":" << ruleAction.interfaceAction() << "requires a" << ifaceActionParamType.name() << "param of type" << QVariant::typeToName(ifaceActionParamType.type());
|
||||
if (!ruleExitAction.ruleActionParams().hasParam(ifaceActionParamType.name())) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action" << iface.name() << ":" << ruleExitAction.interfaceAction() << "requires a" << ifaceActionParamType.name() << "param of type" << QVariant::typeToName(ifaceActionParamType.type());
|
||||
return RuleError::RuleErrorMissingParameter;
|
||||
}
|
||||
if (!ruleAction.ruleActionParam(ifaceActionParamType.name()).value().canConvert(ifaceActionParamType.type())) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action parameter" << iface.name() << ":" << ruleAction.interfaceAction() << ":" << ifaceActionParamType.name() << "has wrong type. Expected" << QVariant::typeToName(ifaceActionParamType.type());
|
||||
if (!ruleExitAction.ruleActionParam(ifaceActionParamType.name()).value().canConvert(ifaceActionParamType.type())) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create rule. Interface action parameter" << iface.name() << ":" << ruleExitAction.interfaceAction() << ":" << ifaceActionParamType.name() << "has wrong type. Expected" << QVariant::typeToName(ifaceActionParamType.type());
|
||||
return RuleError::RuleErrorInvalidParameter;
|
||||
}
|
||||
}
|
||||
// TODO: Check params
|
||||
}
|
||||
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleExitAction.ruleActionParams()) {
|
||||
if (ruleActionParam.isEventBased()) {
|
||||
// We have an eventTypeId, see if the rule actually has such a event
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. Exit actions cannot be event based.";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
} else if (ruleActionParam.isStateBased()) {
|
||||
Device *d = NymeaCore::instance()->deviceManager()->findConfiguredDevice(ruleActionParam.deviceId());
|
||||
if (!d) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot create Rule. DeviceId from RuleAction" << ruleExitAction.actionTypeId() << "not found in system.";
|
||||
return RuleErrorDeviceNotFound;
|
||||
}
|
||||
DeviceClass stateDeviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(d->deviceClassId());
|
||||
StateType stateType = stateDeviceClass.stateTypes().findById(ruleActionParam.stateTypeId());
|
||||
QVariant::Type actionParamType = getActionParamType(ruleExitAction.actionTypeId(), ruleActionParam.paramTypeId());
|
||||
QVariant v(stateType.type());
|
||||
if (actionParamType != stateType.type() && !v.canConvert(static_cast<int>(actionParamType))) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. RuleActionParam" << ruleActionParam.paramTypeId().toString() << " and given state based param " << ruleActionParam.stateTypeId().toString() << "have not the same type:";
|
||||
qCWarning(dcRuleEngine) << " -> actionParamType:" << actionParamType;
|
||||
qCWarning(dcRuleEngine) << " -> stateType:" << stateType.type();
|
||||
return RuleErrorTypesNotMatching;
|
||||
}
|
||||
} else {
|
||||
if (ruleActionParam.value().isNull()) {
|
||||
qCDebug(dcRuleEngine()) << "Cannot create rule. No param value given for action:" << ruleActionParam.paramTypeId().toString();
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
QVariant::Type actionParamType = getActionParamType(ruleExitAction.actionTypeId(), ruleActionParam.paramTypeId());
|
||||
if (ruleActionParam.value().type() != actionParamType && !ruleActionParam.value().canConvert(static_cast<int>(actionParamType))) {
|
||||
qCDebug(dcRuleEngine()) << "Cannot create rule. Given param value for action" << ruleActionParam.paramTypeId().toString() << "does not match type";
|
||||
return RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const RuleActionParam &ruleActionParam, ruleExitAction.ruleActionParams()) {
|
||||
if (!ruleActionParam.isValid()) {
|
||||
qCWarning(dcRuleEngine) << "Cannot create rule. There must be only one out of \"value\", \"eventTypeId/eventParamTypeID\" or \"deviceId/stateTypeId\".";
|
||||
return RuleEngine::RuleErrorInvalidRuleActionParameter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -698,9 +717,9 @@ RuleEngine::RuleError RuleEngine::disableRule(const RuleId &ruleId)
|
|||
*/
|
||||
RuleEngine::RuleError RuleEngine::executeActions(const RuleId &ruleId)
|
||||
{
|
||||
// check if rule exits
|
||||
// check if rule exists
|
||||
if (!m_rules.contains(ruleId)) {
|
||||
qCWarning(dcRuleEngine) << "Not executing rule actions: rule not found.";
|
||||
qCWarning(dcRuleEngine) << "Not executing rule actions: Rule not found.";
|
||||
return RuleErrorRuleNotFound;
|
||||
}
|
||||
|
||||
|
|
@ -1203,11 +1222,14 @@ void RuleEngine::saveRule(const Rule &rule)
|
|||
} else {
|
||||
settings.beginGroup("RuleActionParam-" + param.paramName());
|
||||
}
|
||||
settings.setValue("valueType", (int)param.value().type());
|
||||
settings.setValue("valueType", static_cast<int>(param.value().type()));
|
||||
settings.setValue("value", param.value());
|
||||
if (param.eventTypeId() != EventTypeId()) {
|
||||
if (param.isEventBased()) {
|
||||
settings.setValue("eventTypeId", param.eventTypeId().toString());
|
||||
settings.setValue("eventParamTypeId", param.eventParamTypeId());
|
||||
} else if (param.isStateBased()) {
|
||||
settings.setValue("deviceId", param.deviceId().toString());
|
||||
settings.setValue("stateTypeId", param.stateTypeId());
|
||||
}
|
||||
settings.endGroup();
|
||||
}
|
||||
|
|
@ -1276,7 +1298,7 @@ void RuleEngine::init()
|
|||
|
||||
QList<int> weekDays;
|
||||
QList<int> monthDays;
|
||||
RepeatingOption::RepeatingMode mode = (RepeatingOption::RepeatingMode)settings.value("mode", 0).toInt();
|
||||
RepeatingOption::RepeatingMode mode = static_cast<RepeatingOption::RepeatingMode>(settings.value("mode", 0).toInt());
|
||||
|
||||
// Load weekDays
|
||||
int weekDaysCount = settings.beginReadArray("weekDays");
|
||||
|
|
@ -1313,7 +1335,7 @@ void RuleEngine::init()
|
|||
|
||||
QList<int> weekDays;
|
||||
QList<int> monthDays;
|
||||
RepeatingOption::RepeatingMode mode = (RepeatingOption::RepeatingMode)settings.value("mode", 0).toInt();
|
||||
RepeatingOption::RepeatingMode mode = static_cast<RepeatingOption::RepeatingMode>(settings.value("mode", 0).toInt());
|
||||
|
||||
// Load weekDays
|
||||
int weekDaysCount = settings.beginReadArray("weekDays");
|
||||
|
|
@ -1414,6 +1436,8 @@ void RuleEngine::init()
|
|||
QString strippedParamTypeIdString = paramTypeIdString.remove(QRegExp("^RuleActionParam-"));
|
||||
EventTypeId eventTypeId = EventTypeId(settings.value("eventTypeId", EventTypeId()).toString());
|
||||
ParamTypeId eventParamTypeId = ParamTypeId(settings.value("eventParamTypeId", ParamTypeId()).toString());
|
||||
DeviceId deviceId = DeviceId(settings.value("deviceId", DeviceId()).toString());
|
||||
StateTypeId stateTypeId = StateTypeId(settings.value("stateTypeId", StateTypeId()).toString());
|
||||
QVariant value = settings.value("value");
|
||||
if (settings.contains("valueType")) {
|
||||
QVariant::Type valueType = (QVariant::Type)settings.value("valueType").toInt();
|
||||
|
|
@ -1427,19 +1451,20 @@ void RuleEngine::init()
|
|||
}
|
||||
}
|
||||
|
||||
RuleActionParam param;
|
||||
if (!ParamTypeId(strippedParamTypeIdString).isNull()) {
|
||||
RuleActionParam param(ParamTypeId(strippedParamTypeIdString),
|
||||
value,
|
||||
eventTypeId,
|
||||
eventParamTypeId);
|
||||
params.append(param);
|
||||
// By ParamTypeId
|
||||
param = RuleActionParam(ParamTypeId(strippedParamTypeIdString), value);
|
||||
} else {
|
||||
RuleActionParam param(strippedParamTypeIdString,
|
||||
value,
|
||||
eventTypeId,
|
||||
eventParamTypeId);
|
||||
params.append(param);
|
||||
// By param name
|
||||
param = RuleActionParam(strippedParamTypeIdString, value);
|
||||
}
|
||||
param.setEventTypeId(eventTypeId);
|
||||
param.setEventParamTypeId(eventParamTypeId);
|
||||
param.setDeviceId(deviceId);
|
||||
param.setStateTypeId(stateTypeId);
|
||||
params.append(param);
|
||||
params.append(param);
|
||||
settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ QDateTime TimeEventItem::dateTime() const
|
|||
}
|
||||
|
||||
/*! Sets the dateTime of this \l{TimeEventItem} to the given \a timeStamp. */
|
||||
void TimeEventItem::setDateTime(const int &timeStamp)
|
||||
void TimeEventItem::setDateTime(const uint &timeStamp)
|
||||
{
|
||||
m_dateTime = QDateTime::fromTime_t(timeStamp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public:
|
|||
TimeEventItem();
|
||||
|
||||
QDateTime dateTime() const;
|
||||
void setDateTime(const int &timeStamp);
|
||||
void setDateTime(const uint &timeStamp);
|
||||
|
||||
QTime time() const;
|
||||
void setTime(const QTime &time);
|
||||
|
|
|
|||
|
|
@ -99,7 +99,17 @@ RuleAction::Type RuleAction::type() const
|
|||
bool RuleAction::isEventBased() const
|
||||
{
|
||||
foreach (const RuleActionParam ¶m, m_ruleActionParams) {
|
||||
if (param.eventTypeId() != EventTypeId()) {
|
||||
if (param.isEventBased()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RuleAction::isStateBased() const
|
||||
{
|
||||
foreach (const RuleActionParam ¶m, m_ruleActionParams) {
|
||||
if (param.isStateBased()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -167,7 +177,7 @@ RuleActionParam RuleAction::ruleActionParam(const ParamTypeId &ruleActionParamTy
|
|||
return ruleActionParam;
|
||||
}
|
||||
}
|
||||
return RuleActionParam(QString());
|
||||
return RuleActionParam();
|
||||
}
|
||||
|
||||
/*! Returns the \l{RuleActionParam} of this RuleAction with the given \a ruleActionParamName.
|
||||
|
|
@ -180,7 +190,7 @@ RuleActionParam RuleAction::ruleActionParam(const QString &ruleActionParamName)
|
|||
return ruleActionParam;
|
||||
}
|
||||
}
|
||||
return RuleActionParam(QString());
|
||||
return RuleActionParam();
|
||||
}
|
||||
|
||||
/*! Copy the data to a \l{RuleAction} from an \a other rule action. */
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
Type type() const;
|
||||
|
||||
bool isEventBased() const;
|
||||
bool isStateBased() const;
|
||||
|
||||
Action toAction() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,21 @@
|
|||
A RuleActionParam allows rules to take over an \l{Event} parameter into a rule
|
||||
\l{RuleAction}.
|
||||
|
||||
RuleActionParams are identified by either paramTypeId or paramName (for interface based actions).
|
||||
|
||||
The parameter value can either be a static \l{value}, a pair of \l{EventTypeId} and \l{ParamTypeId} or a pair of
|
||||
\l{DeviceId} and \l{StateTypeId}.
|
||||
|
||||
When composing the actual Param for the executeAction() call the value is generated as follows:
|
||||
- Static value params are filled with \l{RuleActionParam::paramTypeId()} and the \l{RuleActionParam::value()}
|
||||
- Event based actions are filled with \l{RuleActionParam::paramTypeId()} and the param value of the event that triggered this rule, identified by \l{RuleActionParam::eventTypeId()} and \l{RuleActionParam::eventParamTypeId()}
|
||||
- State based actions are filled with \l{RuleActionParam::paramTypeId()} and the current value of the state identified by \l{RuleActionParam::deviceId()} and \l{RuleActionParam::stateTypeId()}
|
||||
|
||||
If the param types are not matching, nymea will do a best effort to cast the values. E.g. a RuleActionParam for
|
||||
a param of type "string" and a state of type "int" would cast the integer to a string which would always work.
|
||||
However, the other way round, having a parameter requiring an "int" value, and reading the value from a state of type
|
||||
"string" might work, if the string does only hold numbers but would fail.
|
||||
|
||||
\sa nymeaserver::Rule, RuleAction,
|
||||
*/
|
||||
|
||||
|
|
@ -41,33 +56,68 @@
|
|||
* \sa Param, */
|
||||
RuleActionParam::RuleActionParam(const Param ¶m) :
|
||||
m_paramTypeId(param.paramTypeId()),
|
||||
m_value(param.value()),
|
||||
m_eventTypeId(EventTypeId()),
|
||||
m_eventParamTypeId(ParamTypeId())
|
||||
m_value(param.value())
|
||||
{
|
||||
}
|
||||
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramTypeId, \a value, \a eventTypeId and \a eventParamTypeId.
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramTypeId and \a value.
|
||||
* \sa Param, Event, */
|
||||
RuleActionParam::RuleActionParam(const ParamTypeId ¶mTypeId, const QVariant &value, const EventTypeId &eventTypeId, const ParamTypeId &eventParamTypeId) :
|
||||
RuleActionParam::RuleActionParam(const ParamTypeId ¶mTypeId, const QVariant &value):
|
||||
m_paramTypeId(paramTypeId),
|
||||
m_value(value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramTypeId, \a eventTypeId and \a eventParamTypeId.
|
||||
* \sa Param, Event, */
|
||||
RuleActionParam::RuleActionParam(const ParamTypeId ¶mTypeId, const EventTypeId &eventTypeId, const ParamTypeId &eventParamTypeId):
|
||||
m_paramTypeId(paramTypeId),
|
||||
m_value(value),
|
||||
m_eventTypeId(eventTypeId),
|
||||
m_eventParamTypeId(eventParamTypeId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramName, \a value, \a eventTypeId and \a eventParamTypeId.
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramTypeId, \a deviceId and \a stateTypeId.
|
||||
* \sa Param, Event, */
|
||||
RuleActionParam::RuleActionParam(const QString ¶mName, const QVariant &value, const EventTypeId &eventTypeId, const ParamTypeId &eventParamTypeId):
|
||||
RuleActionParam::RuleActionParam(const ParamTypeId ¶mTypeId, const DeviceId &deviceId, const StateTypeId &stateTypeId):
|
||||
m_paramTypeId(paramTypeId),
|
||||
m_deviceId(deviceId),
|
||||
m_stateTypeId(stateTypeId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramName and \a value.
|
||||
* \sa Param, Event, */
|
||||
RuleActionParam::RuleActionParam(const QString ¶mName, const QVariant &value):
|
||||
m_paramName(paramName),
|
||||
m_value(value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramName, \a eventTypeId and \a eventParamTypeId.
|
||||
* \sa Param, Event, */
|
||||
RuleActionParam::RuleActionParam(const QString ¶mName, const EventTypeId &eventTypeId, const ParamTypeId &eventParamTypeId):
|
||||
m_paramName(paramName),
|
||||
m_value(value),
|
||||
m_eventTypeId(eventTypeId),
|
||||
m_eventParamTypeId(eventParamTypeId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Constructs a \l{RuleActionParam} with the given \a paramName, \a deviceId and \a stateTypeId.
|
||||
* \sa Param, Event, */
|
||||
RuleActionParam::RuleActionParam(const QString ¶mName, const DeviceId &deviceId, const StateTypeId &stateTypeId):
|
||||
m_paramName(paramName),
|
||||
m_deviceId(deviceId),
|
||||
m_stateTypeId(stateTypeId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! Returns the \l ParamTypeId of this \l RuleActionParam. */
|
||||
ParamTypeId RuleActionParam::paramTypeId() const
|
||||
{
|
||||
|
|
@ -80,18 +130,6 @@ QString RuleActionParam::paramName() const
|
|||
return m_paramName;
|
||||
}
|
||||
|
||||
/*! Returns the eventParamTypeId of this RuleActionParam. */
|
||||
ParamTypeId RuleActionParam::eventParamTypeId() const
|
||||
{
|
||||
return m_eventParamTypeId;
|
||||
}
|
||||
|
||||
/*! Sets the \a eventParamTypeId of this RuleActionParam. */
|
||||
void RuleActionParam::setEventParamTypeId(const ParamTypeId &eventParamTypeId)
|
||||
{
|
||||
m_eventParamTypeId = eventParamTypeId;
|
||||
}
|
||||
|
||||
/*! Returns the value of this RuleActionParam. */
|
||||
QVariant RuleActionParam::value() const
|
||||
{
|
||||
|
|
@ -104,14 +142,6 @@ void RuleActionParam::setValue(const QVariant &value)
|
|||
m_value = value;
|
||||
}
|
||||
|
||||
/*! Returns true if the \tt{(paramTypeId AND value) XOR (paramTypeId AND eventTypeId AND eventParamName)} of this RuleActionParam are set.*/
|
||||
bool RuleActionParam::isValid() const
|
||||
{
|
||||
bool validValue = (!m_paramTypeId.isNull() && m_value.isValid() && m_eventTypeId.isNull() && m_eventParamTypeId.isNull());
|
||||
bool validEvent = (!m_paramTypeId.isNull() && !m_value.isValid() && !m_eventTypeId.isNull() && !m_eventParamTypeId.isNull());
|
||||
return validValue ^ validEvent;
|
||||
}
|
||||
|
||||
/*! Return the EventTypeId of the \l{Event} with the \l{Param} which will be taken over in the \l{RuleAction}. */
|
||||
EventTypeId RuleActionParam::eventTypeId() const
|
||||
{
|
||||
|
|
@ -124,6 +154,66 @@ void RuleActionParam::setEventTypeId(const EventTypeId &eventTypeId)
|
|||
m_eventTypeId = eventTypeId;
|
||||
}
|
||||
|
||||
/*! Returns the eventParamTypeId of this RuleActionParam. */
|
||||
ParamTypeId RuleActionParam::eventParamTypeId() const
|
||||
{
|
||||
return m_eventParamTypeId;
|
||||
}
|
||||
|
||||
/*! Sets the \a eventParamTypeId of this RuleActionParam. */
|
||||
void RuleActionParam::setEventParamTypeId(const ParamTypeId &eventParamTypeId)
|
||||
{
|
||||
m_eventParamTypeId = eventParamTypeId;
|
||||
}
|
||||
|
||||
/*! Returns the deviceId identifying the device to use a state value from. */
|
||||
DeviceId RuleActionParam::deviceId() const
|
||||
{
|
||||
return m_deviceId;
|
||||
}
|
||||
|
||||
/*! Sets the deviceId identifying the device to use a state value from. */
|
||||
void RuleActionParam::setDeviceId(const DeviceId &deviceId)
|
||||
{
|
||||
m_deviceId = deviceId;
|
||||
}
|
||||
|
||||
/*! Returns the stateTypeId identifying the state to use the value. */
|
||||
StateTypeId RuleActionParam::stateTypeId() const
|
||||
{
|
||||
return m_stateTypeId;
|
||||
}
|
||||
|
||||
/*! Sets the stateTypeId identifying the state to use the value from. */
|
||||
void RuleActionParam::setStateTypeId(const StateTypeId &stateTypeId)
|
||||
{
|
||||
m_stateTypeId = stateTypeId;
|
||||
}
|
||||
|
||||
/*! Returns true if the \tt{(paramTypeId AND value) XOR (paramTypeId AND eventTypeId AND eventParamName)} of this RuleActionParam are set.*/
|
||||
bool RuleActionParam::isValid() const
|
||||
{
|
||||
if (m_paramTypeId.isNull() && m_paramName.isNull()) {
|
||||
return false;
|
||||
}
|
||||
return isValueBased() ^ isEventBased() ^ isStateBased();
|
||||
}
|
||||
|
||||
bool RuleActionParam::isValueBased() const
|
||||
{
|
||||
return !m_value.isNull();
|
||||
}
|
||||
|
||||
bool RuleActionParam::isEventBased() const
|
||||
{
|
||||
return !m_eventTypeId.isNull() && !m_eventParamTypeId.isNull();
|
||||
}
|
||||
|
||||
bool RuleActionParam::isStateBased() const
|
||||
{
|
||||
return !m_deviceId.isNull() && !m_stateTypeId.isNull();
|
||||
}
|
||||
|
||||
/*! Writes the paramTypeId, value, eventId and eventParamTypeId of the given \a ruleActionParam to \a dbg. */
|
||||
QDebug operator<<(QDebug dbg, const RuleActionParam &ruleActionParam)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,29 +36,46 @@ class LIBNYMEA_EXPORT RuleActionParam
|
|||
{
|
||||
public:
|
||||
RuleActionParam(const Param ¶m = Param());
|
||||
RuleActionParam(const ParamTypeId ¶mTypeId, const QVariant &value = QVariant(), const EventTypeId &eventTypeId = EventTypeId(), const ParamTypeId &eventParamTypeId = ParamTypeId());
|
||||
RuleActionParam(const QString ¶mName, const QVariant &value = QVariant(), const EventTypeId &eventTypeId = EventTypeId(), const ParamTypeId &eventParamTypeId = ParamTypeId());
|
||||
RuleActionParam(const ParamTypeId ¶mTypeId, const QVariant &value = QVariant());
|
||||
RuleActionParam(const ParamTypeId ¶mTypeId, const EventTypeId &eventTypeId, const ParamTypeId &eventParamTypeId);
|
||||
RuleActionParam(const ParamTypeId ¶mTypeId, const DeviceId &deviceId, const StateTypeId &stateTypeId);
|
||||
RuleActionParam(const QString ¶mName, const QVariant &value = QVariant());
|
||||
RuleActionParam(const QString ¶mName, const EventTypeId &eventTypeId, const ParamTypeId &eventParamTypeId);
|
||||
RuleActionParam(const QString ¶mName, const DeviceId &deviceId, const StateTypeId &stateTypeId);
|
||||
|
||||
ParamTypeId paramTypeId() const;
|
||||
QString paramName() const;
|
||||
|
||||
ParamTypeId eventParamTypeId() const;
|
||||
void setEventParamTypeId(const ParamTypeId &eventParamTypeId);
|
||||
bool isValid() const;
|
||||
bool isValueBased() const;
|
||||
bool isEventBased() const;
|
||||
bool isStateBased() const;
|
||||
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
EventTypeId eventTypeId() const;
|
||||
void setEventTypeId(const EventTypeId &eventTypeId);
|
||||
|
||||
ParamTypeId eventParamTypeId() const;
|
||||
void setEventParamTypeId(const ParamTypeId &eventParamTypeId);
|
||||
|
||||
DeviceId deviceId() const;
|
||||
void setDeviceId(const DeviceId &deviceId);
|
||||
|
||||
StateTypeId stateTypeId() const;
|
||||
void setStateTypeId(const StateTypeId &stateTypeId);
|
||||
|
||||
private:
|
||||
ParamTypeId m_paramTypeId;
|
||||
QString m_paramName;
|
||||
QVariant m_value;
|
||||
|
||||
EventTypeId m_eventTypeId;
|
||||
ParamTypeId m_eventParamTypeId;
|
||||
|
||||
DeviceId m_deviceId;
|
||||
StateTypeId m_stateTypeId;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(RuleActionParam)
|
||||
|
|
|
|||
|
|
@ -93,9 +93,10 @@ private slots:
|
|||
void enableDisableRule();
|
||||
|
||||
void testEventBasedAction();
|
||||
|
||||
void testEventBasedRuleWithExitAction();
|
||||
|
||||
void testStateBasedAction();
|
||||
|
||||
void removePolicyUpdate();
|
||||
void removePolicyCascade();
|
||||
void removePolicyUpdateRendersUselessRule();
|
||||
|
|
@ -2214,6 +2215,98 @@ void TestRules::testEventBasedRuleWithExitAction()
|
|||
|
||||
}
|
||||
|
||||
void TestRules::testStateBasedAction()
|
||||
{
|
||||
QNetworkAccessManager nam;
|
||||
QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*)));
|
||||
|
||||
// Init bool state to true
|
||||
spy.clear();
|
||||
QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockBoolStateId.toString()).arg(true)));
|
||||
QNetworkReply *reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
|
||||
// Init int state to 11
|
||||
spy.clear();
|
||||
request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockIntStateId.toString()).arg(11)));
|
||||
reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
|
||||
// Add a rule
|
||||
QVariantMap addRuleParams;
|
||||
QVariantMap eventDescriptor;
|
||||
eventDescriptor.insert("eventTypeId", mockEvent1Id);
|
||||
eventDescriptor.insert("deviceId", m_mockDeviceId);
|
||||
addRuleParams.insert("eventDescriptors", QVariantList() << eventDescriptor);
|
||||
addRuleParams.insert("name", "TestRule");
|
||||
addRuleParams.insert("enabled", true);
|
||||
|
||||
QVariantList actions;
|
||||
QVariantMap action;
|
||||
QVariantList ruleActionParams;
|
||||
QVariantMap param1;
|
||||
param1.insert("paramTypeId", mockActionParam1ParamTypeId);
|
||||
param1.insert("deviceId", m_mockDeviceId);
|
||||
param1.insert("stateTypeId", mockIntStateId);
|
||||
QVariantMap param2;
|
||||
param2.insert("paramTypeId", mockActionParam2ParamTypeId);
|
||||
param2.insert("deviceId", m_mockDeviceId);
|
||||
param2.insert("stateTypeId", mockBoolStateId);
|
||||
ruleActionParams.append(param1);
|
||||
ruleActionParams.append(param2);
|
||||
|
||||
actions.clear();
|
||||
action.insert("deviceId", m_mockDeviceId);
|
||||
action.insert("actionTypeId", mockActionIdWithParams);
|
||||
action.insert("ruleActionParams", ruleActionParams);
|
||||
actions.append(action);
|
||||
addRuleParams.insert("actions", actions);
|
||||
|
||||
qDebug() << addRuleParams;
|
||||
|
||||
QVariant response = injectAndWait("Rules.AddRule", addRuleParams);
|
||||
verifyRuleError(response);
|
||||
|
||||
// trigger event
|
||||
spy.clear();
|
||||
request = QNetworkRequest(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(m_mockDevice1Port).arg(mockEvent1Id.toString())));
|
||||
reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
|
||||
LogFilter filter;
|
||||
filter.addDeviceId(m_mockDeviceId);
|
||||
filter.addTypeId(mockActionIdWithParams);
|
||||
QList<LogEntry> entries = NymeaCore::instance()->logEngine()->logEntries(filter);
|
||||
qCDebug(dcTests()) << "Log entries:" << entries;
|
||||
|
||||
// set bool state to false
|
||||
spy.clear();
|
||||
request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockDevice1Port).arg(mockBoolStateId.toString()).arg(false)));
|
||||
reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
|
||||
// trigger event
|
||||
spy.clear();
|
||||
request = QNetworkRequest(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(m_mockDevice1Port).arg(mockEvent1Id.toString())));
|
||||
reply = nam.get(request);
|
||||
spy.wait();
|
||||
QCOMPARE(spy.count(), 1);
|
||||
reply->deleteLater();
|
||||
|
||||
entries = NymeaCore::instance()->logEngine()->logEntries(filter);
|
||||
qCDebug(dcTests()) << "Log entries:" << entries;
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TestRules::removePolicyUpdate()
|
||||
{
|
||||
// ADD parent device
|
||||
|
|
|
|||
Loading…
Reference in New Issue