add device parent child relation

add remove policy to REST
expand remove policy
This commit is contained in:
Simon Stürz 2015-10-20 13:35:52 +02:00 committed by Michael Zanetti
parent fb6aa3e068
commit fc9b6f1887
14 changed files with 290 additions and 63 deletions

View File

@ -741,6 +741,18 @@ QList<Device *> DeviceManager::findConfiguredDevices(const DeviceClassId &device
return ret;
}
/*! Returns all child \l{Device}{Devices} of the given \a device. */
QList<Device *> DeviceManager::findChildDevices(Device *device) const
{
QList<Device *> ret;
foreach (Device *d, m_configuredDevices) {
if (d->parentId() == device->id()) {
ret.append(d);
}
}
return ret;
}
/*! For conveninece, this returns the \l{DeviceClass} with the id given by \a deviceClassId.
* Note: The returned \l{DeviceClass} may be invalid. */
DeviceClass DeviceManager::findDeviceClass(const DeviceClassId &deviceClassId) const
@ -881,6 +893,7 @@ void DeviceManager::loadConfiguredDevices()
settings.beginGroup(idString);
Device *device = new Device(PluginId(settings.value("pluginid").toString()), DeviceId(idString), DeviceClassId(settings.value("deviceClassId").toString()), this);
device->setName(settings.value("devicename").toString());
device->setParentId(DeviceId(settings.value("parentid", QUuid()).toString()));
ParamList params;
settings.beginGroup("Params");
@ -914,6 +927,9 @@ void DeviceManager::storeConfiguredDevices()
settings.setValue("devicename", device->name());
settings.setValue("deviceClassId", device->deviceClassId().toString());
settings.setValue("pluginid", device->pluginId().toString());
if (!device->parentId().isNull())
settings.setValue("parentid", device->parentId().toString());
settings.beginGroup("Params");
foreach (const Param &param, device->params()) {
settings.setValue(param.name(), param.value());

View File

@ -82,6 +82,8 @@ public:
DeviceErrorAuthentificationFailure,
DeviceErrorAsync,
DeviceErrorDeviceInUse,
DeviceErrorDeviceInRule,
DeviceErrorDeviceIsChild,
DeviceErrorPairingTransactionIdNotFound,
DeviceErrorParameterNotWritable
};
@ -119,7 +121,8 @@ public:
DeviceError removeConfiguredDevice(const DeviceId &deviceId);
Device* findConfiguredDevice(const DeviceId &id) const;
QList<Device*> findConfiguredDevices(const DeviceClassId &deviceClassId) const;
QList<Device *> findConfiguredDevices(const DeviceClassId &deviceClassId) const;
QList<Device *> findChildDevices(Device *device) const;
DeviceClass findDeviceClass(const DeviceClassId &deviceClassId) const;
signals:

View File

@ -45,7 +45,7 @@ void UpnpDiscoveryRequest::discover()
m_upnpDiscovery->sendToMulticast(ssdpSearchMessage);
qCDebug(dcHardware) << "--> UPnP discovery called.";
m_timer->start(3000);
m_timer->start(5000);
}
void UpnpDiscoveryRequest::addDeviceDescriptor(const UpnpDeviceDescriptor &deviceDescriptor)

View File

@ -154,7 +154,7 @@ bool Device::hasParam(const QString &paramName) const
return false;
}
/*! Sets the \a states of this Device. It must match the \l{StateType} description in the associated \l{DeviceClass}. */
DeviceId m_id;
void Device::setStates(const QList<State> &states)
{
m_states = states;
@ -211,6 +211,22 @@ State Device::state(const StateTypeId &stateTypeId) const
return State(StateTypeId(), DeviceId());
}
/*! Returns the \l{DeviceId} of the parent Device from Device. If the parentId
is not set, this device is a parent device.
*/
DeviceId Device::parentId() const
{
return m_parentId;
}
/*! Sets the \a parentId of this Device. If the parentId
is not set, this device is a parent device.
*/
void Device::setParentId(const DeviceId &parentId)
{
m_parentId = parentId;
}
/*! Returns true, if setup of this Device is already completed. */
bool Device::setupComplete() const
{

View File

@ -32,7 +32,6 @@
#include <QUuid>
#include <QVariant>
class Device: public QObject
{
Q_OBJECT
@ -63,6 +62,9 @@ public:
State state(const StateTypeId &stateTypeId) const;
DeviceId parentId() const;
void setParentId(const DeviceId &parentId);
bool setupComplete() const;
signals:
@ -77,6 +79,7 @@ private:
private:
DeviceId m_id;
DeviceId m_parentId;
DeviceClassId m_deviceClassId;
PluginId m_pluginId;
QString m_name;

View File

@ -85,6 +85,7 @@ DeviceManager::DeviceError DevicePluginPhilipsHue::discoverDevices(const DeviceC
{
Q_UNUSED(deviceClassId)
Q_UNUSED(params)
upnpDiscover("libhue:idl");
return DeviceManager::DeviceErrorAsync;
}
@ -164,10 +165,9 @@ DeviceManager::DeviceSetupStatus DevicePluginPhilipsHue::setupDevice(Device *dev
device->paramValue("model id").toString(),
DeviceId(device->paramValue("bridge").toString()),
this);
connect(hueLight, &HueLight::stateChanged, this, &DevicePluginPhilipsHue::lightStateChanged);
}
device->setParentId(device->paramValue("bridge").toString());
m_lights.insert(hueLight, device);
setLightName(device, device->paramValue("name").toString());
}
@ -181,8 +181,6 @@ void DevicePluginPhilipsHue::deviceRemoved(Device *device)
HueBridge *bridge = m_bridges.key(device);
m_bridges.remove(bridge);
bridge->deleteLater();
// TODO: remove lights from this bridge (over GuhCore)
}
if (device->deviceClassId() == hueLightDeviceClassId) {
@ -321,7 +319,6 @@ void DevicePluginPhilipsHue::networkManagerReplyReady(QNetworkReply *reply)
return;
}
processSetNameResponse(device, reply->readAll());
}
reply->deleteLater();

View File

@ -14,7 +14,7 @@
"name": "Hue Bridge",
"createMethods": ["discovery"],
"setupMethod": "pushButton",
"pairingInfo": "Please press within 30 seconds the button on the Hue Bridge before you continue",
"pairingInfo": "Please press the button on the Hue Bridge within 30 seconds before you continue",
"paramTypes": [
{
"name": "name",

View File

@ -180,11 +180,44 @@ QList<DeviceClass> GuhCore::supportedDevices(const VendorId &vendorId) const
}
/*! Removes a configured \l{Device} with the given \a deviceId and \a removePolicyList. */
DeviceManager::DeviceError GuhCore::removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList)
QPair<DeviceManager::DeviceError, QList<RuleId> > GuhCore::removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList)
{
// Check if this is a child device
Device *device = findConfiguredDevice(deviceId);
if (!device->parentId().isNull()) {
qCWarning(dcDeviceManager) << "The device is a child of" << device->parentId().toString() << ". Please remove the parent device.";
return QPair<DeviceManager::DeviceError, QList<RuleId> > (DeviceManager::DeviceErrorDeviceIsChild, QList<RuleId>());
}
// Check if this device has child devices
QList<Device *> devicesToRemove;
devicesToRemove.append(device);
QList<Device *> childDevices = m_deviceManager->findChildDevices(device);
if (!childDevices.isEmpty()) {
foreach (Device *child, childDevices) {
devicesToRemove.append(child);
}
}
// check devices
QList<RuleId> offendingRules;
qCDebug(dcDeviceManager) << "Devices to remove:";
foreach (Device *d, devicesToRemove) {
qCDebug(dcDeviceManager) << " -> " << d->name() << d->id().toString();
// Check if device is in a rule
foreach (const RuleId &ruleId, m_ruleEngine->findRules(d->id())) {
qCDebug(dcDeviceManager) << " -> in rule:" << ruleId.toString();
if (!offendingRules.contains(ruleId)) {
offendingRules.append(ruleId);
}
}
}
// check each offending rule if there is a corresponding remove policy
QHash<RuleId, RuleEngine::RemovePolicy> toBeChanged;
QList<RuleId> unhandledRules;
foreach (const RuleId &ruleId, m_ruleEngine->findRules(deviceId)) {
foreach (const RuleId &ruleId, offendingRules) {
bool found = false;
foreach (const RuleId &policyRuleId, removePolicyList.keys()) {
if (ruleId == policyRuleId) {
@ -193,14 +226,14 @@ DeviceManager::DeviceError GuhCore::removeConfiguredDevice(const DeviceId &devic
break;
}
}
if (!found) {
if (!found)
unhandledRules.append(ruleId);
}
}
if (!unhandledRules.isEmpty()) {
qCWarning(dcDeviceManager) << "There are unhandled rules which depend on this device.";
return DeviceManager::DeviceErrorDeviceInUse;
qCWarning(dcDeviceManager) << "There are unhandled rules which depend on this device:\n" << unhandledRules;
return QPair<DeviceManager::DeviceError, QList<RuleId> > (DeviceManager::DeviceErrorDeviceInRule, unhandledRules);
}
// Update the rules...
@ -208,13 +241,87 @@ DeviceManager::DeviceError GuhCore::removeConfiguredDevice(const DeviceId &devic
if (toBeChanged.value(ruleId) == RuleEngine::RemovePolicyCascade) {
m_ruleEngine->removeRule(ruleId);
} else if (toBeChanged.value(ruleId) == RuleEngine::RemovePolicyUpdate){
m_ruleEngine->removeDeviceFromRule(ruleId, deviceId);
foreach (Device *d, devicesToRemove) {
m_ruleEngine->removeDeviceFromRule(ruleId, d->id());
}
}
}
// remove the child devices
foreach (Device *d, childDevices) {
DeviceManager::DeviceError removeError = m_deviceManager->removeConfiguredDevice(d->id());
if (removeError == DeviceManager::DeviceErrorNoError) {
m_logger->removeDeviceLogs(d->id());
}
}
// delete the devices
DeviceManager::DeviceError removeError = m_deviceManager->removeConfiguredDevice(deviceId);
if (removeError == DeviceManager::DeviceErrorNoError)
if (removeError == DeviceManager::DeviceErrorNoError) {
m_logger->removeDeviceLogs(deviceId);
}
return QPair<DeviceManager::DeviceError, QList<RuleId> > (DeviceManager::DeviceErrorNoError, QList<RuleId>());
}
DeviceManager::DeviceError GuhCore::removeConfiguredDevice(const DeviceId &deviceId, const RuleEngine::RemovePolicy &removePolicy)
{
// Check if this is a child device
Device *device = findConfiguredDevice(deviceId);
if (!device->parentId().isNull()) {
qCWarning(dcDeviceManager) << "The device is a child of" << device->parentId().toString() << ". Please remove the parent device.";
return DeviceManager::DeviceErrorDeviceIsChild;
}
// Check if this device has child devices
QList<Device *> devicesToRemove;
devicesToRemove.append(device);
QList<Device *> childDevices = m_deviceManager->findChildDevices(device);
if (!childDevices.isEmpty()) {
foreach (Device *child, childDevices) {
devicesToRemove.append(child);
}
}
// check devices
QList<RuleId> offendingRules;
qCDebug(dcDeviceManager) << "Devices to remove:";
foreach (Device *d, devicesToRemove) {
qCDebug(dcDeviceManager) << " -> " << d->name() << d->id().toString();
// Check if device is in a rule
foreach (const RuleId &ruleId, m_ruleEngine->findRules(d->id())) {
qCDebug(dcDeviceManager) << " -> in rule:" << ruleId.toString();
if (!offendingRules.contains(ruleId)) {
offendingRules.append(ruleId);
}
}
}
// apply removepolicy for foreach rule
foreach (const RuleId &ruleId, offendingRules) {
if (removePolicy == RuleEngine::RemovePolicyCascade) {
m_ruleEngine->removeRule(ruleId);
} else if (removePolicy == RuleEngine::RemovePolicyUpdate){
foreach (Device *d, devicesToRemove) {
m_ruleEngine->removeDeviceFromRule(ruleId, d->id());
}
}
}
// remove the child devices
foreach (Device *d, childDevices) {
DeviceManager::DeviceError removeError = m_deviceManager->removeConfiguredDevice(d->id());
if (removeError == DeviceManager::DeviceErrorNoError) {
m_logger->removeDeviceLogs(d->id());
}
}
// delete the devices
DeviceManager::DeviceError removeError = m_deviceManager->removeConfiguredDevice(deviceId);
if (removeError == DeviceManager::DeviceErrorNoError) {
m_logger->removeDeviceLogs(deviceId);
}
return removeError;
}

View File

@ -70,12 +70,13 @@ public:
DeviceManager::DeviceError discoverDevices(const DeviceClassId &deviceClassId, const ParamList &params);
DeviceManager::DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const ParamList &params, const DeviceId &newId);
DeviceManager::DeviceError addConfiguredDevice(const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId, const DeviceId &newId);
QList<Device*> configuredDevices() const;
QList<Device *> configuredDevices() const;
Device *findConfiguredDevice(const DeviceId &deviceId) const;
QList<Device*> findConfiguredDevices(const DeviceClassId &deviceClassId) const;
QList<Device *> findConfiguredDevices(const DeviceClassId &deviceClassId) const;
DeviceManager::DeviceError editDevice(const DeviceId &deviceId, const ParamList &params);
DeviceManager::DeviceError editDevice(const DeviceId &deviceId, const DeviceDescriptorId &deviceDescriptorId);
DeviceManager::DeviceError removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList);
QPair<DeviceManager::DeviceError, QList<RuleId> >removeConfiguredDevice(const DeviceId &deviceId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList);
DeviceManager::DeviceError removeConfiguredDevice(const DeviceId &deviceId, const RuleEngine::RemovePolicy &removePolicy);
DeviceManager::DeviceError pairDevice(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const DeviceDescriptorId &deviceDescriptorId);
DeviceManager::DeviceError pairDevice(const PairingTransactionId &pairingTransactionId, const DeviceClassId &deviceClassId, const ParamList &params);
@ -120,7 +121,6 @@ signals:
void ruleActiveChanged(const Rule &rule);
void ruleConfigurationChanged(const Rule &rule);
private:
RuleEngine *ruleEngine() const;

View File

@ -113,13 +113,13 @@ DeviceHandler::DeviceHandler(QObject *parent) :
returns.clear(); // Reused params from above!
setDescription("PairDevice", "Pair a device. "
"Use this for DeviceClasses with a setupMethod different than SetupMethodJustAdd."
"Use this for DeviceClasses with a setupMethod different than SetupMethodJustAdd. "
"Use deviceDescriptorId or deviceParams, depending on the createMethod of the device class. "
"CreateMethodJustAdd takes the parameters you want to have with that device. "
"CreateMethodDiscovery requires the use of a deviceDescriptorId. "
"If success is true, the return values will contain a pairingTransactionId, a displayMessage and "
"the setupMethod. Depending on the setupMethod you should either proceed with AddConfiguredDevice "
" or PairDevice."
"or PairDevice."
);
setParams("PairDevice", params);
returns.insert("deviceError", JsonTypes::deviceErrorRef());
@ -181,9 +181,11 @@ DeviceHandler::DeviceHandler(QObject *parent) :
policy.insert("ruleId", JsonTypes::basicTypeToString(JsonTypes::Uuid));
policy.insert("policy", JsonTypes::removePolicyRef());
removePolicyList.append(policy);
params.insert("o:removePolicy", JsonTypes::removePolicyRef());
params.insert("o:removePolicyList", removePolicyList);
setParams("RemoveConfiguredDevice", params);
returns.insert("deviceError", JsonTypes::deviceErrorRef());
returns.insert("o:ruleIds", QVariantList() << JsonTypes::basicTypeToString(JsonTypes::Uuid));
setReturns("RemoveConfiguredDevice", returns);
params.clear(); returns.clear();
@ -459,7 +461,17 @@ JsonReply *DeviceHandler::EditDevice(const QVariantMap &params)
JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap &params)
{
QVariantMap returns;
DeviceId deviceId = DeviceId(params.value("deviceId").toString());
// global removePolicy has priority
if (params.contains("removePolicy")) {
RuleEngine::RemovePolicy removePolicy = params.value("removePolicy").toString() == "RemovePolicyCascade" ? RuleEngine::RemovePolicyCascade : RuleEngine::RemovePolicyUpdate;
DeviceManager::DeviceError status = GuhCore::instance()->removeConfiguredDevice(deviceId, removePolicy);
returns.insert("deviceError", JsonTypes::deviceErrorToString(status));
return createReply(returns);
}
QHash<RuleId, RuleEngine::RemovePolicy> removePolicyList;
foreach (const QVariant &variant, params.value("removePolicyList").toList()) {
RuleId ruleId = RuleId(variant.toMap().value("ruleId").toString());
@ -467,9 +479,17 @@ JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap &params)
removePolicyList.insert(ruleId, policy);
}
QVariantMap returns;
DeviceManager::DeviceError status = GuhCore::instance()->removeConfiguredDevice(deviceId, removePolicyList);
returns.insert("deviceError", JsonTypes::deviceErrorToString(status));
QPair<DeviceManager::DeviceError, QList<RuleId> > status = GuhCore::instance()->removeConfiguredDevice(deviceId, removePolicyList);
returns.insert("deviceError", JsonTypes::deviceErrorToString(status.first));
if (!status.second.isEmpty()) {
QVariantList ruleIdList;
foreach (const RuleId &ruleId, status.second) {
ruleIdList.append(ruleId.toString());
}
returns.insert("ruleIds", ruleIdList);
}
return createReply(returns);
}
@ -614,7 +634,6 @@ void DeviceHandler::deviceSetupFinished(Device *device, DeviceManager::DeviceErr
}
reply->setData(returns);
reply->finished();
}
void DeviceHandler::deviceEditFinished(Device *device, DeviceManager::DeviceError status)

View File

@ -199,6 +199,7 @@ void JsonTypes::init()
s_device.insert("name", basicTypeToString(String));
s_device.insert("params", QVariantList() << paramRef());
s_device.insert("setupComplete", basicTypeToString(Bool));
s_device.insert("o:parentId", basicTypeToString(Uuid));
// DeviceDescription
s_deviceDescriptor.insert("id", basicTypeToString(Uuid));
@ -561,6 +562,10 @@ QVariantMap JsonTypes::packDevice(Device *device)
foreach (const Param &param, device->params()) {
params.append(packParam(param));
}
if (!device->parentId().isNull())
variant.insert("parentId", device->parentId());
variant.insert("params", params);
variant.insert("setupComplete", device->setupComplete());
return variant;

View File

@ -155,10 +155,19 @@ HttpReply *DevicesResource::proccessDeleteRequest(const HttpRequest &request, co
return createErrorReply(HttpReply::BadRequest);
// DELETE /api/v1/devices/{deviceId}
if (urlTokens.count() == 4)
return removeDevice(m_device);
if (urlTokens.count() == 4) {
QVariantMap params;
if (request.urlQuery().hasQueryItem("params")) {
QString paramMapString = request.urlQuery().queryItemValue("params");
// TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy}
QPair<bool, QVariant> verification = verifyPayload(paramMapString.toUtf8());
if (!verification.first)
return createErrorReply(HttpReply::BadRequest);
params = verification.second.toMap();
}
return removeDevice(m_device, params);
}
return createErrorReply(HttpReply::NotImplemented);
}
@ -232,19 +241,8 @@ HttpReply *DevicesResource::getConfiguredDevices() const
{
qCDebug(dcRest) << "Get all configured devices";
HttpReply *reply = createSuccessReply();
QVariantList devices = JsonTypes::packConfiguredDevices();
QVariantList finalDevices;
foreach (const QVariant &deviceVariant, devices) {
QVariantMap deviceMap = deviceVariant.toMap();
Device* device = GuhCore::instance()->findConfiguredDevice(DeviceId(deviceMap.value("id").toString()));
QVariantList deviceStates = JsonTypes::packDeviceStates(device);
deviceMap.insert("states", deviceStates);
finalDevices.append(deviceMap);
}
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
reply->setPayload(QJsonDocument::fromVariant(finalDevices).toJson());
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packConfiguredDevices()).toJson());
return reply;
}
@ -252,14 +250,8 @@ HttpReply *DevicesResource::getConfiguredDevice(Device *device) const
{
qCDebug(dcRest) << "Get configured device with id:" << device->id().toString();
HttpReply *reply = createSuccessReply();
QVariantMap deviceMap = JsonTypes::packDevice(device);
QVariantList deviceStates = JsonTypes::packDeviceStates(device);
deviceMap.insert("states", deviceStates);
qCDebug(dcRest) << deviceMap;
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
reply->setPayload(QJsonDocument::fromVariant(deviceMap).toJson());
reply->setPayload(QJsonDocument::fromVariant(JsonTypes::packDevice(device)).toJson());
return reply;
}
@ -283,18 +275,49 @@ HttpReply *DevicesResource::getDeviceStateValue(Device *device, const StateTypeI
return reply;
}
HttpReply *DevicesResource::removeDevice(Device *device) const
HttpReply *DevicesResource::removeDevice(Device *device, const QVariantMap &params) const
{
qCDebug(dcRest) << "Remove device with id:" << device->id().toString();
DeviceManager::DeviceError result = GuhCore::instance()->removeConfiguredDevice(device->id(), QHash<RuleId, RuleEngine::RemovePolicy>());
qCDebug(dcRest) << QJsonDocument::fromVariant(params).toJson();
// TODO: /api/v1/devices/{deviceId}?ruleId={ruleId}&removePolicy={RemovePolicy}
// global removePolicy has priority
if (params.contains("removePolicy")) {
RuleEngine::RemovePolicy removePolicy = params.value("removePolicy").toString() == "RemovePolicyCascade" ? RuleEngine::RemovePolicyCascade : RuleEngine::RemovePolicyUpdate;
DeviceManager::DeviceError result = GuhCore::instance()->removeConfiguredDevice(device->id(), removePolicy);
return createDeviceErrorReply(HttpReply::Ok, result);
}
if (result == DeviceManager::DeviceErrorNoError) {
HttpReply *reply = createDeviceErrorReply(HttpReply::Ok, result);
QHash<RuleId, RuleEngine::RemovePolicy> removePolicyList;
foreach (const QVariant &variant, params.value("removePolicyList").toList()) {
RuleId ruleId = RuleId(variant.toMap().value("ruleId").toString());
RuleEngine::RemovePolicy policy = variant.toMap().value("policy").toString() == "RemovePolicyCascade" ? RuleEngine::RemovePolicyCascade : RuleEngine::RemovePolicyUpdate;
removePolicyList.insert(ruleId, policy);
}
QPair<DeviceManager::DeviceError, QList<RuleId> > status = GuhCore::instance()->removeConfiguredDevice(device->id(), removePolicyList);
// if there are offending rules
if (!status.second.isEmpty()) {
QVariantList ruleIdList;
QVariantMap returns;
returns.insert("deviceError", JsonTypes::deviceErrorToString(status.first));
foreach (const RuleId &ruleId, status.second) {
ruleIdList.append(ruleId.toString());
}
returns.insert("ruleIds", ruleIdList);
HttpReply *reply = createErrorReply(HttpReply::BadRequest);
reply->setHeader(HttpReply::ContentTypeHeader, "application/json; charset=\"utf-8\";");
reply->setPayload(QJsonDocument::fromVariant(returns).toJson());
return reply;
}
return createDeviceErrorReply(HttpReply::BadRequest, result);
if (status.first == DeviceManager::DeviceErrorNoError)
return createDeviceErrorReply(HttpReply::Ok, status.first);
return createDeviceErrorReply(HttpReply::BadRequest, status.first);
}
HttpReply *DevicesResource::executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const

View File

@ -64,7 +64,7 @@ private:
HttpReply *getDeviceStateValue(Device *device, const StateTypeId &stateTypeId) const;
// Delete methods
HttpReply *removeDevice(Device *device) const;
HttpReply *removeDevice(Device *device, const QVariantMap &params) const;
// Post methods
HttpReply *executeAction(Device *device, const ActionTypeId &actionTypeId, const QByteArray &payload) const;

View File

@ -551,9 +551,10 @@ QList<RuleId> RuleEngine::findRules(const DeviceId &deviceId)
break;
}
}
if (!offending && rule.stateEvaluator().containsDevice(deviceId)) {
if (!offending && rule.stateEvaluator().containsDevice(deviceId))
offending = true;
}
if (!offending) {
foreach (const RuleAction &action, rule.actions()) {
if (action.deviceId() == deviceId) {
@ -562,9 +563,19 @@ QList<RuleId> RuleEngine::findRules(const DeviceId &deviceId)
}
}
}
if (offending) {
offendingRules.append(rule.id());
if (!offending) {
foreach (const RuleAction &action, rule.exitActions()) {
if (action.deviceId() == deviceId) {
offending = true;
break;
}
}
}
if (offending)
offendingRules.append(rule.id());
}
return offendingRules;
}
@ -572,10 +583,12 @@ QList<RuleId> RuleEngine::findRules(const DeviceId &deviceId)
/*! Removes a \l{Device} from a \l{Rule} with the given \a id and \a deviceId. */
void RuleEngine::removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId)
{
if (!m_rules.contains(id)) {
if (!m_rules.contains(id))
return;
}
Rule rule = m_rules.value(id);
// remove device from eventDescriptors
QList<EventDescriptor> eventDescriptors = rule.eventDescriptors();
QList<int> removeIndexes;
for (int i = 0; i < eventDescriptors.count(); i++) {
@ -586,9 +599,12 @@ void RuleEngine::removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId
while (removeIndexes.count() > 0) {
eventDescriptors.takeAt(removeIndexes.takeLast());
}
// remove device from state evaluators
StateEvaluator stateEvalatuator = rule.stateEvaluator();
stateEvalatuator.removeDevice(deviceId);
// remove device from actions
QList<RuleAction> actions = rule.actions();
for (int i = 0; i < actions.count(); i++) {
if (actions.at(i).deviceId() == deviceId) {
@ -598,8 +614,30 @@ void RuleEngine::removeDeviceFromRule(const RuleId &id, const DeviceId &deviceId
while (removeIndexes.count() > 0) {
actions.takeAt(removeIndexes.takeLast());
}
// remove device from exit actions
QList<RuleAction> exitActions = rule.exitActions();
for (int i = 0; i < exitActions.count(); i++) {
if (exitActions.at(i).deviceId() == deviceId) {
removeIndexes.append(i);
}
}
while (removeIndexes.count() > 0) {
exitActions.takeAt(removeIndexes.takeLast());
}
// remove the rule from settings
GuhSettings settings(GuhSettings::SettingsRoleRules);
settings.beginGroup(id.toString());
settings.remove("");
settings.endGroup();
Rule newRule(id, rule.name(), eventDescriptors, stateEvalatuator, actions);
m_rules[id] = newRule;
// save it
saveRule(newRule);
emit ruleConfigurationChanged(newRule);
}
bool RuleEngine::containsEvent(const Rule &rule, const Event &event)