diff --git a/libnymea-core/jsonrpc/actionhandler.cpp b/libnymea-core/jsonrpc/actionhandler.cpp deleted file mode 100644 index b9f2999f..00000000 --- a/libnymea-core/jsonrpc/actionhandler.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "actionhandler.h" -#include "devicehandler.h" - -#include "nymeacore.h" -#include "integrations/thingmanager.h" -#include "integrations/thingactioninfo.h" -#include "integrations/browseractioninfo.h" -#include "integrations/browseritemactioninfo.h" -#include "types/action.h" -#include "types/actiontype.h" -#include "loggingcategories.h" - -namespace nymeaserver { - -ActionHandler::ActionHandler(QObject *parent) : - JsonHandler(parent) -{ - // Enums - registerEnum(); - registerEnum(); - - // Objects - registerObject(); - registerObject(); - registerObject(); - registerObject(); - - // Methods - QString description; QVariantMap params; QVariantMap returns; - description = "Execute a single action."; - params.insert("actionTypeId", enumValueName(Uuid)); - params.insert("deviceId", enumValueName(Uuid)); - params.insert("o:params", objectRef()); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - registerMethod("ExecuteAction", description, params, returns, "Please use Integrations.ExecuteAction instead."); - - params.clear(); returns.clear(); - description = "Get the ActionType for the given ActionTypeId."; - params.insert("actionTypeId", enumValueName(Uuid)); - returns.insert("deviceError", enumRef()); - returns.insert("o:actionType", objectRef()); - registerMethod("GetActionType", description, params, returns, "Please use the Integrations namespace instead."); - - params.clear(); returns.clear(); - description = "Execute the item identified by itemId on the given device."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("itemId", enumValueName(String)); - returns.insert("deviceError", enumRef()); - registerMethod("ExecuteBrowserItem", description, params, returns, "Please use Integrations.ExecuteBrowserItem instead."); - - params.clear(); returns.clear(); - description = "Execute the action for the browser item identified by actionTypeId and the itemId on the given device."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("itemId", enumValueName(String)); - params.insert("actionTypeId", enumValueName(Uuid)); - params.insert("o:params", objectRef()); - returns.insert("deviceError", enumRef()); - registerMethod("ExecuteBrowserItemAction", description, params, returns, "Please use Integrations.ExecuteBrowserItem instead."); - -} - -QString ActionHandler::name() const -{ - return "Actions"; -} - -JsonReply* ActionHandler::ExecuteAction(const QVariantMap ¶ms, const JsonContext &context) -{ - ThingId thingId(params.value("deviceId").toString()); - ActionTypeId actionTypeId(params.value("actionTypeId").toString()); - ParamList actionParams = unpack(params.value("params")); - QLocale locale = context.locale(); - - Action action(actionTypeId, thingId); - action.setParams(actionParams); - - JsonReply *jsonReply = createAsyncReply("ExecuteAction"); - - ThingActionInfo *info = NymeaCore::instance()->thingManager()->executeAction(action); - connect(info, &ThingActionInfo::finished, jsonReply, [info, jsonReply, locale](){ - QVariantMap data; - data.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - if (!info->displayMessage().isEmpty()) { - data.insert("displayMessage", info->translatedDisplayMessage(locale)); - } - jsonReply->setData(data); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply *ActionHandler::GetActionType(const QVariantMap ¶ms, const JsonContext &context) const -{ - QLocale locale = context.locale(); - qCDebug(dcJsonRpc) << "asked for action type" << params; - ActionTypeId actionTypeId(params.value("actionTypeId").toString()); - foreach (const ThingClass &deviceClass, NymeaCore::instance()->thingManager()->supportedThings()) { - foreach (const ActionType &actionType, deviceClass.actionTypes()) { - if (actionType.id() == actionTypeId) { - ActionType translatedActionType = actionType; - translatedActionType.setDisplayName(NymeaCore::instance()->thingManager()->translate(deviceClass.pluginId(), actionType.displayName(), locale)); - - QVariantMap data; - data.insert("deviceError", enumValueName(Thing::ThingErrorNoError).replace("ThingError", "DeviceError")); - data.insert("actionType", pack(translatedActionType)); - return createReply(data); - } - } - } - QVariantMap data; - data.insert("deviceError", enumValueName(Thing::ThingErrorActionTypeNotFound).replace("ThingError", "DeviceError")); - return createReply(data); -} - -JsonReply *ActionHandler::ExecuteBrowserItem(const QVariantMap ¶ms) -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - QString itemId = params.value("itemId").toString(); - BrowserAction action(thingId, itemId); - - JsonReply *jsonReply = createAsyncReply("ExecuteBrowserItem"); - - BrowserActionInfo *info = NymeaCore::instance()->executeBrowserItem(action); - connect(info, &BrowserActionInfo::finished, jsonReply, [info, jsonReply](){ - QVariantMap data; - data.insert("deviceError", enumValueName(info->status()).replace("ThingError", "DeviceError")); - jsonReply->setData(data); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply *ActionHandler::ExecuteBrowserItemAction(const QVariantMap ¶ms) -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - QString itemId = params.value("itemId").toString(); - ActionTypeId actionTypeId = ActionTypeId(params.value("actionTypeId").toString()); - ParamList paramList = unpack(params.value("params")); - BrowserItemAction browserItemAction(thingId, itemId, actionTypeId, paramList); - - JsonReply *jsonReply = createAsyncReply("ExecuteBrowserItemAction"); - - BrowserItemActionInfo *info = NymeaCore::instance()->executeBrowserItemAction(browserItemAction); - connect(info, &BrowserItemActionInfo::finished, jsonReply, [info, jsonReply](){ - QVariantMap data; - data.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - jsonReply->setData(data); - jsonReply->finished(); - }); - - return jsonReply; -} - -} diff --git a/libnymea-core/jsonrpc/actionhandler.h b/libnymea-core/jsonrpc/actionhandler.h deleted file mode 100644 index 30ab6151..00000000 --- a/libnymea-core/jsonrpc/actionhandler.h +++ /dev/null @@ -1,57 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef ACTIONHANDLER_H -#define ACTIONHANDLER_H - -#include "jsonrpc/jsonhandler.h" -#include "integrations/thingmanager.h" - -namespace nymeaserver { - -class ActionHandler : public JsonHandler -{ - Q_OBJECT -public: - explicit ActionHandler(QObject *parent = nullptr); - - QString name() const override; - - Q_INVOKABLE JsonReply *ExecuteAction(const QVariantMap ¶ms, const JsonContext &context); - Q_INVOKABLE JsonReply *GetActionType(const QVariantMap ¶ms, const JsonContext &context) const; - - Q_INVOKABLE JsonReply *ExecuteBrowserItem(const QVariantMap ¶ms); - Q_INVOKABLE JsonReply *ExecuteBrowserItemAction(const QVariantMap ¶ms); - -}; - -} - -#endif // ACTIONHANDLER_H diff --git a/libnymea-core/jsonrpc/devicehandler.cpp b/libnymea-core/jsonrpc/devicehandler.cpp deleted file mode 100644 index 8d52bf3d..00000000 --- a/libnymea-core/jsonrpc/devicehandler.cpp +++ /dev/null @@ -1,1092 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "devicehandler.h" -#include "nymeacore.h" -#include "integrations/thingmanager.h" -#include "integrations/thing.h" -#include "integrations/integrationplugin.h" -#include "loggingcategories.h" -#include "types/thingclass.h" -#include "types/browseritem.h" -#include "types/mediabrowseritem.h" -#include "integrations/translator.h" -#include "integrations/thingdiscoveryinfo.h" -#include "integrations/thingpairinginfo.h" -#include "integrations/thingsetupinfo.h" -#include "integrations/browseresult.h" -#include "integrations/browseritemresult.h" - -#include -#include - -namespace nymeaserver { - -DeviceHandler::DeviceHandler(QObject *parent) : - JsonHandler(parent) -{ - // Enums - registerEnum(); - registerEnum(); - registerEnum(); - registerEnum(); - registerEnum(); - registerFlag(); - registerEnum(); - registerEnum(); - registerEnum(); - registerEnum(); - registerEnum(); - registerEnum(); - registerEnum(); - - // Objects - registerObject(); - registerObject(); - registerUncreatableObject(); - registerUncreatableObject(); - registerObject(); - registerObject(); - registerObject(); - registerObject(); - registerObject(); - registerObject(); - registerObject(); - registerObject(); - registerObject(); - registerObject(); - registerUncreatableObject(); - registerUncreatableObject(); - - // Regsitering browseritem manually for now. Not sure how to deal with the - // polymorphism in int (e.g MediaBrowserItem) - QVariantMap browserItem; - browserItem.insert("id", enumValueName(String)); - browserItem.insert("displayName", enumValueName(String)); - browserItem.insert("description", enumValueName(String)); - browserItem.insert("icon", enumRef()); - browserItem.insert("thumbnail", enumValueName(String)); - browserItem.insert("executable", enumValueName(Bool)); - browserItem.insert("browsable", enumValueName(Bool)); - browserItem.insert("disabled", enumValueName(Bool)); - browserItem.insert("actionTypeIds", QVariantList() << enumValueName(Uuid)); - browserItem.insert("o:mediaIcon", enumRef()); - registerObject("BrowserItem", browserItem); - - - // Methods - QString description; QVariantMap returns; QVariantMap params; - description = "Returns a list of supported Vendors."; - returns.insert("vendors", objectRef()); - registerMethod("GetSupportedVendors", description, params, returns); - - params.clear(); returns.clear(); - description = "Returns a list of supported Device classes, optionally filtered by vendorId."; - params.insert("o:vendorId", enumValueName(Uuid)); - returns.insert("deviceClasses", objectRef()); - registerMethod("GetSupportedDevices", description, params, returns); - - params.clear(); returns.clear(); - description = "Returns a list of loaded plugins."; - returns.insert("plugins", objectRef()); - registerMethod("GetPlugins", description, params, returns); - - params.clear(); returns.clear(); - description = "Get a plugin's params."; - params.insert("pluginId", enumValueName(Uuid)); - returns.insert("deviceError", enumRef()); - returns.insert("o:configuration", objectRef()); - registerMethod("GetPluginConfiguration", description, params, returns); - - params.clear(); returns.clear(); - description = "Set a plugin's params."; - params.insert("pluginId", enumValueName(Uuid)); - params.insert("configuration", objectRef()); - returns.insert("deviceError", enumRef()); - registerMethod("SetPluginConfiguration", description, params, returns); - - params.clear(); returns.clear(); - description = "Add a configured device with a setupMethod of SetupMethodJustAdd. " - "For devices with a setupMethod different than SetupMethodJustAdd, use PairDevice. " - "Devices with CreateMethodJustAdd require all parameters to be supplied here. " - "Devices with CreateMethodDiscovery require the use of a deviceDescriptorId. For discovered " - "devices params are not required and will be taken from the DeviceDescriptor, however, they " - "may be overridden by supplying deviceParams."; - params.insert("deviceClassId", enumValueName(Uuid)); - params.insert("name", enumValueName(String)); - params.insert("o:deviceDescriptorId", enumValueName(Uuid)); - params.insert("o:deviceParams", objectRef()); - returns.insert("deviceError", enumRef()); - returns.insert("o:deviceId", enumValueName(Uuid)); - returns.insert("o:displayMessage", enumValueName(String)); - registerMethod("AddConfiguredDevice", description, params, returns); - - params.clear(); returns.clear(); - description = "Pair a device. " - "Use this to set up or reconfigure devices for DeviceClasses with a setupMethod different than SetupMethodJustAdd. " - "Depending on the CreateMethod and whether a new devices is set up or an existing one is reconfigured, different parameters " - "are required:\n" - "CreateMethodJustAdd takes the deviceClassId and the parameters to be used with that device. " - "If an existing device should be reconfigured, the deviceId of said device should be given additionally.\n" - "CreateMethodDiscovery requires the use of a deviceDescriptorId, previously obtained with DiscoverDevices. Optionally, " - "parameters can be overridden with the give deviceParams. DeviceDescriptors containing a deviceId will reconfigure that " - "device, descriptors without deviceId will add a new one.\n" - "If success is true, the return values will contain a pairingTransactionId, a displayMessage and " - "the setupMethod. Depending on the setupMethod, the application should present the use an appropriate login mask, " - "that is, For SetupMethodDisplayPin the user should enter a pin that is displayed on the device, for SetupMethodEnterPin the " - "application should present the given PIN so the user can enter it on the device. For SetupMethodPushButton, the displayMessage " - "shall be presented to the user as informational hints to press a button on the device. For SetupMethodUserAndPassword a login " - "mask for a user and password login should be presented to the user. In case of SetupMethodOAuth, an OAuth URL will be returned " - "which shall be opened in a web view to allow the user logging in.\n" - "Once the login procedure has completed, the application shall proceed with ConfirmPairing, providing the results of the pairing " - "procedure."; - params.insert("o:deviceClassId", enumValueName(Uuid)); - params.insert("o:name", enumValueName(String)); - params.insert("o:deviceDescriptorId", enumValueName(Uuid)); - params.insert("o:deviceParams", objectRef()); - params.insert("o:deviceId", enumValueName(Uuid)); - returns.insert("deviceError", enumRef()); - returns.insert("o:setupMethod", enumRef()); - returns.insert("o:pairingTransactionId", enumValueName(Uuid)); - returns.insert("o:displayMessage", enumValueName(String)); - returns.insert("o:oAuthUrl", enumValueName(String)); - returns.insert("o:pin", enumValueName(String)); - registerMethod("PairDevice", description, params, returns); - - params.clear(); returns.clear(); - description = "Confirm an ongoing pairing. For SetupMethodUserAndPassword, provide the username in the \"username\" field " - "and the password in the \"secret\" field. For SetupMethodEnterPin and provide the PIN in the \"secret\" " - "field. In case of SetupMethodOAuth, the previously opened web view will eventually be redirected to http://128.0.0.1:8888 " - "and the OAuth code as query parameters to this url. Provide the entire unmodified URL in the secret field."; - params.insert("pairingTransactionId", enumValueName(Uuid)); - params.insert("o:username", enumValueName(String)); - params.insert("o:secret", enumValueName(String)); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - returns.insert("o:deviceId", enumValueName(Uuid)); - registerMethod("ConfirmPairing", description, params, returns); - - params.clear(); returns.clear(); - description = "Returns a list of configured devices, optionally filtered by deviceId."; - params.insert("o:deviceId", enumValueName(Uuid)); - returns.insert("devices", objectRef()); - registerMethod("GetConfiguredDevices", description, params, returns); - - params.clear(); returns.clear(); - description = "Performs a device discovery and returns the results. This function may take a while to return. " - "Note that this method will include all the found devices, that is, including devices that " - "already have been added. Those devices will have deviceId set to the device id of the already " - "added device. Such results may be used to reconfigure existing devices and might be filtered " - "in cases where only unknown devices are of interest."; - params.insert("deviceClassId", enumValueName(Uuid)); - params.insert("o:discoveryParams", objectRef()); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - returns.insert("o:deviceDescriptors", objectRef()); - registerMethod("GetDiscoveredDevices", description, params, returns); - - params.clear(); returns.clear(); - description = "Reconfigure a device. This comes down to removing and recreating a device with new parameters " - "but keeping its device id the same (and with that keeping rules, tags etc). For devices with " - "create method CreateMethodDiscovery, a discovery (GetDiscoveredDevices) shall be performed first " - "and this method is to be called with a deviceDescriptorId of the re-discovered device instead of " - "the deviceId directly. Device parameters will be taken from the discovery, but can be overridden " - "individually here by providing them in the deviceParams parameter. Only writable parameters can " - "be changed."; - params.insert("o:deviceId", enumValueName(Uuid)); - params.insert("o:deviceDescriptorId", enumValueName(Uuid)); - params.insert("o:deviceParams", objectRef()); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - registerMethod("ReconfigureDevice", description, params, returns); - - params.clear(); returns.clear(); - description = "Edit the name of a device. This method does not change the " - "configuration of the device."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("name", enumValueName(String)); - returns.insert("deviceError", enumRef()); - registerMethod("EditDevice", description, params, returns); - - params.clear(); returns.clear(); - description = "Change the settings of a device."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("settings", objectRef()); - returns.insert("deviceError", enumRef()); - registerMethod("SetDeviceSettings", description, params, returns); - - params.clear(); returns.clear(); - description = "Remove a device from the system."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("o:removePolicy", enumRef()); - QVariantMap policy; - policy.insert("ruleId", enumValueName(Uuid)); - policy.insert("policy", enumRef()); - QVariantList removePolicyList; - removePolicyList.append(policy); - params.insert("o:removePolicyList", removePolicyList); - returns.insert("deviceError", enumRef()); - returns.insert("o:ruleIds", QVariantList() << enumValueName(Uuid)); - registerMethod("RemoveConfiguredDevice", description, params, returns); - - params.clear(); returns.clear(); - description = "Get event types for a specified deviceClassId."; - params.insert("deviceClassId", enumValueName(Uuid)); - returns.insert("eventTypes", objectRef()); - registerMethod("GetEventTypes", description, params, returns); - - params.clear(); returns.clear(); - description = "Get action types for a specified deviceClassId."; - params.insert("deviceClassId", enumValueName(Uuid)); - returns.insert("actionTypes", objectRef()); - registerMethod("GetActionTypes", description, params, returns); - - params.clear(); returns.clear(); - description = "Get state types for a specified deviceClassId."; - params.insert("deviceClassId", enumValueName(Uuid)); - returns.insert("stateTypes", objectRef()); - registerMethod("GetStateTypes", description, params, returns); - - params.clear(); returns.clear(); - description = "Get the value of the given device and the given stateType"; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("stateTypeId", enumValueName(Uuid)); - returns.insert("deviceError", enumRef()); - returns.insert("o:value", enumValueName(Variant)); - registerMethod("GetStateValue", description, params, returns); - - params.clear(); returns.clear(); - description = "Get all the state values of the given device."; - params.insert("deviceId", enumValueName(Uuid)); - returns.insert("deviceError", enumRef()); - returns.insert("o:values", objectRef()); - registerMethod("GetStateValues", description, params, returns); - - params.clear(); returns.clear(); - description = "Browse a device. If a DeviceClass indicates a device is browsable, this method will return " - "the BrowserItems. If no parameter besides the deviceId is used, the root node of this device " - "will be returned. Any returned item which is browsable can be passed as node. Results will be " - "children of the given node.\n" - "In case of an error during browsing, the error will be indicated and the displayMessage may contain " - "additional information for the user. The displayMessage will be translated. A client UI showing this " - "message to the user should be prepared for empty, but also longer strings."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("o:itemId", enumValueName(String)); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - returns.insert("items", QVariantList() << objectRef("BrowserItem")); - registerMethod("BrowseDevice", description, params, returns); - - params.clear(); returns.clear(); - description = "Get a single item from the browser. This won't give any more info on an item than a regular browseDevice " - "call, but it allows to fetch details of an item if only the ID is known.\n" - "In case of an error during browsing, the error will be indicated and the displayMessage may contain " - "additional information for the user. The displayMessage will be translated. A client UI showing this " - "message to the user should be prepared for empty, but also longer strings."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("o:itemId", enumValueName(String)); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - returns.insert("o:item", objectRef("BrowserItem")); - registerMethod("GetBrowserItem", description, params, returns); - - params.clear(); returns.clear(); - description = "Execute a single action."; - params.insert("actionTypeId", enumValueName(Uuid)); - params.insert("deviceId", enumValueName(Uuid)); - params.insert("o:params", objectRef()); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - registerMethod("ExecuteAction", description, params, returns); - - params.clear(); returns.clear(); - description = "Execute the item identified by itemId on the given device.\n" - "In case of an error during execution, the error will be indicated and the displayMessage may contain " - "additional information for the user. The displayMessage will be translated. A client UI showing this " - "message to the user should be prepared for empty, but also longer strings."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("itemId", enumValueName(String)); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - registerMethod("ExecuteBrowserItem", description, params, returns); - - params.clear(); returns.clear(); - description = "Execute the action for the browser item identified by actionTypeId and the itemId on the given device.\n" - "In case of an error during execution, the error will be indicated and the displayMessage may contain " - "additional information for the user. The displayMessage will be translated. A client UI showing this " - "message to the user should be prepared for empty, but also longer strings."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("itemId", enumValueName(String)); - params.insert("actionTypeId", enumValueName(Uuid)); - params.insert("o:params", objectRef()); - returns.insert("deviceError", enumRef()); - returns.insert("o:displayMessage", enumValueName(String)); - registerMethod("ExecuteBrowserItemAction", description, params, returns); - - // Notifications - params.clear(); returns.clear(); - description = "Emitted whenever a State of a device changes."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("stateTypeId", enumValueName(Uuid)); - params.insert("value", enumValueName(Variant)); - registerNotification("StateChanged", description, params); - - params.clear(); returns.clear(); - description = "Emitted whenever a Device was removed."; - params.insert("deviceId", enumValueName(Uuid)); - registerNotification("DeviceRemoved", description, params); - - params.clear(); returns.clear(); - description = "Emitted whenever a Device was added."; - params.insert("device", objectRef()); - registerNotification("DeviceAdded", description, params); - - params.clear(); returns.clear(); - description = "Emitted whenever the params, name or setupStatus of a Device changes."; - params.insert("device", objectRef()); - registerNotification("DeviceChanged", description, params); - - params.clear(); returns.clear(); - description = "Emitted whenever the setting of a Device is changed."; - params.insert("deviceId", enumValueName(Uuid)); - params.insert("paramTypeId", enumValueName(Uuid)); - params.insert("value", enumValueName(Variant)); - registerNotification("DeviceSettingChanged", description, params); - - params.clear(); returns.clear(); - description = "Emitted whenever a plugin's configuration is changed."; - params.insert("pluginId", enumValueName(Uuid)); - params.insert("configuration", objectRef()); - registerNotification("PluginConfigurationChanged", description, params); - - params.clear(); returns.clear(); - description = "Emitted whenever an Event is triggered."; - params.insert("event", objectRef()); - registerNotification("EventTriggered", description, params); - connect(NymeaCore::instance(), &NymeaCore::eventTriggered, this, [this](const Event &event){ - QVariantMap params; - params.insert("event", pack(event)); - emit EventTriggered(params); - }); - - connect(NymeaCore::instance(), &NymeaCore::pluginConfigChanged, this, &DeviceHandler::pluginConfigChanged); - connect(NymeaCore::instance(), &NymeaCore::thingStateChanged, this, &DeviceHandler::deviceStateChanged); - connect(NymeaCore::instance(), &NymeaCore::thingRemoved, this, &DeviceHandler::deviceRemovedNotification); - connect(NymeaCore::instance(), &NymeaCore::thingAdded, this, &DeviceHandler::deviceAddedNotification); - connect(NymeaCore::instance(), &NymeaCore::thingChanged, this, &DeviceHandler::deviceChangedNotification); - connect(NymeaCore::instance(), &NymeaCore::thingSettingChanged, this, &DeviceHandler::deviceSettingChangedNotification); - - connect(NymeaCore::instance(), &NymeaCore::initialized, this, [=](){ - // Generating cache hashes. - // NOTE: We need to sort the lists to get a stable result - QHash thingClassesMap; - foreach (const ThingClass &tc, NymeaCore::instance()->thingManager()->supportedThings()) { - thingClassesMap.insert(tc.id(), tc); - } - QList thingClassIds = thingClassesMap.keys(); - std::sort(thingClassIds.begin(), thingClassIds.end()); - DeviceClasses thingClasses; - foreach (const ThingClassId &id, thingClassIds) { - thingClasses.append(thingClassesMap.value(id)); - } - QByteArray hash = QCryptographicHash::hash(QJsonDocument::fromVariant(pack(thingClasses)).toJson(), QCryptographicHash::Md5).toHex(); - m_cacheHashes.insert("GetSupportedDevices", hash); - - QHash vendorsMap; - foreach (const Vendor &v, NymeaCore::instance()->thingManager()->supportedVendors()) { - vendorsMap.insert(v.id(), v); - } - QList vendorIds = vendorsMap.keys(); - std::sort(vendorIds.begin(), vendorIds.end()); - Vendors vendors; - foreach (const VendorId &id, vendorIds) { - vendors.append(vendorsMap.value(id)); - } - hash = QCryptographicHash::hash(QJsonDocument::fromVariant(pack(vendors)).toJson(), QCryptographicHash::Md5).toHex(); - m_cacheHashes.insert("GetSupportedVendors", hash); - }); - -} - -/*! Returns the name of the \l{DeviceHandler}. In this case \b Devices.*/ -QString DeviceHandler::name() const -{ - return "Devices"; -} - -QHash DeviceHandler::cacheHashes() const -{ - return m_cacheHashes; -} - -JsonReply* DeviceHandler::GetSupportedVendors(const QVariantMap ¶ms, const JsonContext &context) const -{ - Q_UNUSED(params) - QVariantList vendors; - foreach (const Vendor &vendor, NymeaCore::instance()->thingManager()->supportedVendors()) { - Vendor translatedVendor = NymeaCore::instance()->thingManager()->translateVendor(vendor, context.locale()); - vendors.append(pack(translatedVendor)); - } - - QVariantMap returns; - returns.insert("vendors", vendors); - return createReply(returns); -} - -JsonReply* DeviceHandler::GetSupportedDevices(const QVariantMap ¶ms, const JsonContext &context) const -{ - VendorId vendorId = VendorId(params.value("vendorId").toString()); - QVariantMap returns; - QVariantList deviceClasses; - foreach (const DeviceClass &deviceClass, NymeaCore::instance()->thingManager()->supportedThings(vendorId)) { - DeviceClass translatedDeviceClass = NymeaCore::instance()->thingManager()->translateThingClass(deviceClass, context.locale()); - deviceClasses.append(pack(translatedDeviceClass)); - } - - returns.insert("deviceClasses", deviceClasses); - return createReply(returns); -} - -JsonReply *DeviceHandler::GetDiscoveredDevices(const QVariantMap ¶ms, const JsonContext &context) const -{ - QLocale locale = context.locale(); - - QVariantMap returns; - - ThingClassId thingClassId = ThingClassId(params.value("deviceClassId").toString()); - ParamList discoveryParams = unpack(params.value("discoveryParams")); - - JsonReply *reply = createAsyncReply("GetDiscoveredDevices"); - ThingDiscoveryInfo *info = NymeaCore::instance()->thingManager()->discoverThings(thingClassId, discoveryParams); - connect(info, &ThingDiscoveryInfo::finished, reply, [this, reply, info, locale](){ - QVariantMap returns; - returns.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - - if (info->status() == Device::ThingErrorNoError) { - QVariantList deviceDescriptorList; - foreach (const ThingDescriptor &thingDescriptor, info->thingDescriptors()) { - QVariantMap packedDescriptor = pack(thingDescriptor).toMap(); - if (packedDescriptor.contains("thingId")) { - packedDescriptor.insert("deviceId", packedDescriptor.value("thingId")); - } - deviceDescriptorList.append(packedDescriptor); - } - returns.insert("deviceDescriptors", deviceDescriptorList); - } - - if (!info->displayMessage().isEmpty()) { - returns.insert("displayMessage", info->translatedDisplayMessage(locale)); - } - - reply->setData(returns); - reply->finished(); - - }); - return reply; -} - -JsonReply* DeviceHandler::GetPlugins(const QVariantMap ¶ms, const JsonContext &context) const -{ - Q_UNUSED(params) - QVariantList plugins; - foreach (IntegrationPlugin* plugin, NymeaCore::instance()->thingManager()->plugins()) { - QVariantMap packedPlugin = pack(*plugin).toMap(); - packedPlugin["displayName"] = NymeaCore::instance()->thingManager()->translate(plugin->pluginId(), plugin->pluginDisplayName(), context.locale()); - plugins.append(packedPlugin); - } - - QVariantMap returns; - returns.insert("plugins", plugins); - return createReply(returns); -} - -JsonReply *DeviceHandler::GetPluginConfiguration(const QVariantMap ¶ms) const -{ - QVariantMap returns; - - IntegrationPlugin *plugin = NymeaCore::instance()->thingManager()->plugins().findById(PluginId(params.value("pluginId").toString())); - if (!plugin) { - returns.insert("deviceError", enumValueName(Device::ThingErrorPluginNotFound).replace("Thing", "Device")); - return createReply(returns); - } - - QVariantList paramVariantList; - foreach (const Param ¶m, plugin->configuration()) { - paramVariantList.append(pack(param)); - } - returns.insert("configuration", paramVariantList); - returns.insert("deviceError", enumValueName(Device::ThingErrorNoError).replace("Thing", "Device")); - return createReply(returns); -} - -JsonReply* DeviceHandler::SetPluginConfiguration(const QVariantMap ¶ms) -{ - QVariantMap returns; - PluginId pluginId = PluginId(params.value("pluginId").toString()); - ParamList pluginParams = unpack(params.value("configuration")); - Device::ThingError result = NymeaCore::instance()->thingManager()->setPluginConfig(pluginId, pluginParams); - returns.insert("deviceError",enumValueName(result).replace("Thing", "Device")); - return createReply(returns); -} - -JsonReply* DeviceHandler::AddConfiguredDevice(const QVariantMap ¶ms, const JsonContext &context) -{ - ThingClassId thingClassId(params.value("deviceClassId").toString()); - QString deviceName = params.value("name").toString(); - ParamList deviceParams = unpack(params.value("deviceParams")); - ThingDescriptorId deviceDescriptorId(params.value("deviceDescriptorId").toString()); - QLocale locale = context.locale(); - - JsonReply *jsonReply = createAsyncReply("AddConfiguredDevice"); - - ThingSetupInfo *info; - if (deviceDescriptorId.isNull()) { - info = NymeaCore::instance()->thingManager()->addConfiguredThing(thingClassId, deviceParams, deviceName); - } else { - info = NymeaCore::instance()->thingManager()->addConfiguredThing(deviceDescriptorId, deviceParams, deviceName); - } - connect(info, &ThingSetupInfo::finished, jsonReply, [info, jsonReply, locale](){ - QVariantMap returns; - returns.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - - if (!info->displayMessage().isEmpty()) { - returns.insert("displayMessage", info->translatedDisplayMessage(locale)); - } - - if(info->status() == Device::ThingErrorNoError) { - returns.insert("deviceId", info->thing()->id()); - } - jsonReply->setData(returns); - jsonReply->finished(); - - }); - return jsonReply; -} - -JsonReply *DeviceHandler::PairDevice(const QVariantMap ¶ms, const JsonContext &context) -{ - QString deviceName = params.value("name").toString(); - ParamList deviceParams = unpack(params.value("deviceParams")); - QLocale locale = context.locale(); - - ThingPairingInfo *info; - if (params.contains("deviceDescriptorId")) { - ThingDescriptorId deviceDescriptorId = ThingDescriptorId(params.value("deviceDescriptorId").toString()); - info = NymeaCore::instance()->thingManager()->pairThing(deviceDescriptorId, deviceParams, deviceName); - } else if (params.contains("deviceId")) { - ThingId thingId = ThingId(params.value("deviceId").toString()); - info = NymeaCore::instance()->thingManager()->pairThing(thingId, deviceParams, deviceName); - } else { - ThingClassId thingClassId(params.value("deviceClassId").toString()); - info = NymeaCore::instance()->thingManager()->pairThing(thingClassId, deviceParams, deviceName); - } - - JsonReply *jsonReply = createAsyncReply("PairDevice"); - - connect(info, &ThingPairingInfo::finished, jsonReply, [jsonReply, info, locale](){ - QVariantMap returns; - returns.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - returns.insert("pairingTransactionId", info->transactionId().toString()); - - if (info->status() == Device::ThingErrorNoError) { - ThingClass thingClass = NymeaCore::instance()->thingManager()->findThingClass(info->thingClassId()); - returns.insert("setupMethod", enumValueName(thingClass.setupMethod())); - } - - if (!info->displayMessage().isEmpty()) { - returns.insert("displayMessage", info->translatedDisplayMessage(locale)); - } - - if (!info->oAuthUrl().isEmpty()) { - returns.insert("oAuthUrl", info->oAuthUrl()); - } - - jsonReply->setData(returns); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply *DeviceHandler::ConfirmPairing(const QVariantMap ¶ms, const JsonContext &context) -{ - PairingTransactionId pairingTransactionId = PairingTransactionId(params.value("pairingTransactionId").toString()); - QString secret = params.value("secret").toString(); - QString username = params.value("username").toString(); - QLocale locale = context.locale(); - - JsonReply *jsonReply = createAsyncReply("ConfirmPairing"); - - ThingPairingInfo *info = NymeaCore::instance()->thingManager()->confirmPairing(pairingTransactionId, username, secret); - connect(info, &ThingPairingInfo::finished, jsonReply, [info, jsonReply, locale](){ - - QVariantMap returns; - returns.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - if (!info->displayMessage().isEmpty()) { - returns.insert("displayMessage", info->translatedDisplayMessage(locale)); - } - if (info->status() == Device::ThingErrorNoError) { - returns.insert("deviceId", info->thingId().toString()); - } - jsonReply->setData(returns); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply* DeviceHandler::GetConfiguredDevices(const QVariantMap ¶ms, const JsonContext &context) const -{ - QVariantMap returns; - QVariantList configuredDeviceList; - if (params.contains("deviceId")) { - Thing *thing = NymeaCore::instance()->thingManager()->findConfiguredThing(ThingId(params.value("deviceId").toString())); - if (!thing) { - returns.insert("devices", QVariantList()); - return createReply(returns); - } else { - QVariantMap deviceMap = pack(thing).toMap(); - // Patch in deviceClassId - deviceMap.insert("deviceClassId", deviceMap.value("thingClassId")); - configuredDeviceList.append(deviceMap); - } - } else { - foreach (Thing *thing, NymeaCore::instance()->thingManager()->configuredThings()) { - QVariantMap packedThing = pack(thing).toMap(); - QString translatedSetupStatus = NymeaCore::instance()->thingManager()->translate(thing->pluginId(), thing->setupDisplayMessage(), context.locale()); - if (!translatedSetupStatus.isEmpty()) { - packedThing["setupDisplayMessage"] = translatedSetupStatus; - } - // Patch in deviceClassId - packedThing.insert("deviceClassId", packedThing.value("thingClassId")); - configuredDeviceList.append(packedThing); - } - } - returns.insert("devices", configuredDeviceList); - return createReply(returns); -} - -JsonReply *DeviceHandler::ReconfigureDevice(const QVariantMap ¶ms, const JsonContext &context) -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - ParamList deviceParams = unpack(params.value("deviceParams")); - ThingDescriptorId deviceDescriptorId(params.value("deviceDescriptorId").toString()); - QLocale locale = context.locale(); - - JsonReply *jsonReply = createAsyncReply("ReconfigureDevice"); - - ThingSetupInfo *info; - if (!deviceDescriptorId.isNull()) { - info = NymeaCore::instance()->thingManager()->reconfigureThing(deviceDescriptorId, deviceParams); - } else if (!thingId.isNull()){ - info = NymeaCore::instance()->thingManager()->reconfigureThing(thingId, deviceParams); - } else { - qCWarning(dcJsonRpc()) << "Either deviceId or deviceDescriptorId are required"; - QVariantMap ret; - ret.insert("deviceError", enumValueName(Device::ThingErrorMissingParameter)); - return createReply(ret); - } - - connect(info, &ThingSetupInfo::finished, jsonReply, [info, jsonReply, locale](){ - - QVariantMap returns; - returns.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - returns.insert("displayMessage", info->translatedDisplayMessage(locale)); - jsonReply->setData(returns); - jsonReply->finished(); - - }); - - return jsonReply; -} - -JsonReply *DeviceHandler::EditDevice(const QVariantMap ¶ms) -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - QString name = params.value("name").toString(); - - qCDebug(dcJsonRpc()) << "Edit device" << thingId << name; - - Device::ThingError status = NymeaCore::instance()->thingManager()->editThing(thingId, name); - - return createReply(statusToReply(status)); -} - -JsonReply* DeviceHandler::RemoveConfiguredDevice(const QVariantMap ¶ms) -{ - QVariantMap returns; - ThingId thingId = ThingId(params.value("deviceId").toString()); - - // global removePolicy has priority - if (params.contains("removePolicy")) { - RuleEngine::RemovePolicy removePolicy = params.value("removePolicy").toString() == "RemovePolicyCascade" ? RuleEngine::RemovePolicyCascade : RuleEngine::RemovePolicyUpdate; - Device::ThingError status = NymeaCore::instance()->removeConfiguredThing(thingId, removePolicy); - returns.insert("deviceError", enumValueName(status).replace("Thing", "Device")); - return createReply(returns); - } - - QHash 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 > status = NymeaCore::instance()->removeConfiguredThing(thingId, removePolicyList); - returns.insert("deviceError", enumValueName(status.first).replace("Thing", "Device")); - - if (!status.second.isEmpty()) { - QVariantList ruleIdList; - foreach (const RuleId &ruleId, status.second) { - ruleIdList.append(ruleId.toString()); - } - returns.insert("ruleIds", ruleIdList); - } - - return createReply(returns); -} - -JsonReply *DeviceHandler::SetDeviceSettings(const QVariantMap ¶ms) -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - ParamList settings = unpack(params.value("settings")); - Device::ThingError status = NymeaCore::instance()->thingManager()->setThingSettings(thingId, settings); - return createReply(statusToReply(status)); -} - -JsonReply* DeviceHandler::GetEventTypes(const QVariantMap ¶ms, const JsonContext &context) const -{ - ThingClass deviceClass = NymeaCore::instance()->thingManager()->findThingClass(ThingClassId(params.value("deviceClassId").toString())); - ThingClass translatedDeviceClass = NymeaCore::instance()->thingManager()->translateThingClass(deviceClass, context.locale()); - - QVariantMap returns; - returns.insert("eventTypes", pack(translatedDeviceClass.eventTypes())); - return createReply(returns); -} - -JsonReply* DeviceHandler::GetActionTypes(const QVariantMap ¶ms, const JsonContext &context) const -{ - ThingClass deviceClass = NymeaCore::instance()->thingManager()->findThingClass(ThingClassId(params.value("deviceClassId").toString())); - ThingClass translatedDeviceClass = NymeaCore::instance()->thingManager()->translateThingClass(deviceClass, context.locale()); - - QVariantMap returns; - returns.insert("actionTypes", pack(translatedDeviceClass.actionTypes())); - return createReply(returns); -} - -JsonReply* DeviceHandler::GetStateTypes(const QVariantMap ¶ms, const JsonContext &context) const -{ - ThingClass deviceClass = NymeaCore::instance()->thingManager()->findThingClass(ThingClassId(params.value("deviceClassId").toString())); - ThingClass translatedDeviceClass = NymeaCore::instance()->thingManager()->translateThingClass(deviceClass, context.locale()); - - QVariantMap returns; - returns.insert("stateTypes", pack(translatedDeviceClass.stateTypes())); - return createReply(returns); -} - -JsonReply* DeviceHandler::GetStateValue(const QVariantMap ¶ms) const -{ - Thing *thing = NymeaCore::instance()->thingManager()->findConfiguredThing(ThingId(params.value("deviceId").toString())); - if (!thing) { - return createReply(statusToReply(Device::ThingErrorThingNotFound)); - } - StateTypeId stateTypeId = StateTypeId(params.value("stateTypeId").toString()); - if (!thing->hasState(stateTypeId)) { - return createReply(statusToReply(Device::ThingErrorStateTypeNotFound)); - } - - QVariantMap returns = statusToReply(Device::ThingErrorNoError); - returns.insert("value", thing->state(stateTypeId).value()); - return createReply(returns); -} - -JsonReply *DeviceHandler::GetStateValues(const QVariantMap ¶ms) const -{ - Thing *thing = NymeaCore::instance()->thingManager()->findConfiguredThing(ThingId(params.value("deviceId").toString())); - if (!thing) { - return createReply(statusToReply(Device::ThingErrorThingNotFound)); - } - - QVariantMap returns = statusToReply(Device::ThingErrorNoError); - returns.insert("values", pack(thing->states())); - return createReply(returns); -} - -JsonReply *DeviceHandler::BrowseDevice(const QVariantMap ¶ms, const JsonContext &context) const -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - QString itemId = params.value("itemId").toString(); - - JsonReply *jsonReply = createAsyncReply("BrowseDevice"); - - BrowseResult *result = NymeaCore::instance()->thingManager()->browseThing(thingId, itemId, context.locale()); - connect(result, &BrowseResult::finished, jsonReply, [this, jsonReply, result, context](){ - - QVariantMap returns = statusToReply(result->status()); - QVariantList list; - foreach (const BrowserItem &item, result->items()) { - list.append(packBrowserItem(item)); - } - returns.insert("items", list); - if (!result->displayMessage().isEmpty()) { - returns.insert("displayMessage", result->translatedDisplayMessage(context.locale())); - } - jsonReply->setData(returns); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply *DeviceHandler::GetBrowserItem(const QVariantMap ¶ms, const JsonContext &context) const -{ - QVariantMap returns; - ThingId thingId = ThingId(params.value("deviceId").toString()); - QString itemId = params.value("itemId").toString(); - - JsonReply *jsonReply = createAsyncReply("GetBrowserItem"); - - BrowserItemResult *result = NymeaCore::instance()->thingManager()->browserItemDetails(thingId, itemId, context.locale()); - connect(result, &BrowserItemResult::finished, jsonReply, [this, jsonReply, result, context](){ - QVariantMap params = statusToReply(result->status()); - if (result->status() == Device::ThingErrorNoError) { - params.insert("item", packBrowserItem(result->item())); - } - if (!result->displayMessage().isEmpty()) { - params.insert("displayMessage", result->translatedDisplayMessage(context.locale())); - } - jsonReply->setData(params); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply *DeviceHandler::ExecuteAction(const QVariantMap ¶ms, const JsonContext &context) -{ - ThingId thingId(params.value("deviceId").toString()); - ActionTypeId actionTypeId(params.value("actionTypeId").toString()); - ParamList actionParams = unpack(params.value("params")); - QLocale locale = context.locale(); - - Action action(actionTypeId, thingId); - action.setParams(actionParams); - - JsonReply *jsonReply = createAsyncReply("ExecuteAction"); - - ThingActionInfo *info = NymeaCore::instance()->thingManager()->executeAction(action); - connect(info, &ThingActionInfo::finished, jsonReply, [info, jsonReply, locale](){ - QVariantMap data; - data.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - if (!info->displayMessage().isEmpty()) { - data.insert("displayMessage", info->translatedDisplayMessage(locale)); - } - jsonReply->setData(data); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply *DeviceHandler::ExecuteBrowserItem(const QVariantMap ¶ms, const JsonContext &context) -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - QString itemId = params.value("itemId").toString(); - BrowserAction action(thingId, itemId); - - JsonReply *jsonReply = createAsyncReply("ExecuteBrowserItem"); - - BrowserActionInfo *info = NymeaCore::instance()->executeBrowserItem(action); - connect(info, &BrowserActionInfo::finished, jsonReply, [info, jsonReply, context](){ - QVariantMap data; - data.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - if (!info->displayMessage().isEmpty()) { - data.insert("displayMessage", info->translatedDisplayMessage(context.locale())); - } - jsonReply->setData(data); - jsonReply->finished(); - }); - - return jsonReply; -} - -JsonReply *DeviceHandler::ExecuteBrowserItemAction(const QVariantMap ¶ms, const JsonContext &context) -{ - ThingId thingId = ThingId(params.value("deviceId").toString()); - QString itemId = params.value("itemId").toString(); - ActionTypeId actionTypeId = ActionTypeId(params.value("actionTypeId").toString()); - ParamList paramList = unpack(params.value("params")); - BrowserItemAction browserItemAction(thingId, itemId, actionTypeId, paramList); - - JsonReply *jsonReply = createAsyncReply("ExecuteBrowserItemAction"); - - BrowserItemActionInfo *info = NymeaCore::instance()->executeBrowserItemAction(browserItemAction); - connect(info, &BrowserItemActionInfo::finished, jsonReply, [info, jsonReply, context](){ - QVariantMap data; - data.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device")); - if (!info->displayMessage().isEmpty()) { - data.insert("displayMessage", info->translatedDisplayMessage(context.locale())); - } - jsonReply->setData(data); - jsonReply->finished(); - }); - - return jsonReply; -} - -QVariantMap DeviceHandler::packBrowserItem(const BrowserItem &item) -{ - QVariantMap ret; - ret.insert("id", item.id()); - ret.insert("displayName", item.displayName()); - ret.insert("description", item.description()); - ret.insert("icon", enumValueName(item.icon())); - if (item.extendedPropertiesFlags().testFlag(BrowserItem::ExtendedPropertiesMedia)) { - ret.insert("mediaIcon", enumValueName(static_cast(item.extendedProperty("mediaIcon").toInt()))); - } - ret.insert("thumbnail", item.thumbnail()); - ret.insert("executable", item.executable()); - ret.insert("browsable", item.browsable()); - ret.insert("disabled", item.disabled()); - QVariantList actionTypeIds; - foreach (const ActionTypeId &id, item.actionTypeIds()) { - actionTypeIds.append(id.toString()); - } - ret.insert("actionTypeIds", actionTypeIds); - return ret; -} - -void DeviceHandler::pluginConfigChanged(const PluginId &id, const ParamList &config) -{ - QVariantMap params; - params.insert("pluginId", id); - QVariantList configList; - foreach (const Param ¶m, config) { - configList << pack(param); - } - params.insert("configuration", configList); - emit PluginConfigurationChanged(params); -} - -void DeviceHandler::deviceStateChanged(Thing *device, const QUuid &stateTypeId, const QVariant &value) -{ - QVariantMap params; - params.insert("deviceId", device->id()); - params.insert("stateTypeId", stateTypeId); - params.insert("value", value); - emit StateChanged(params); -} - -void DeviceHandler::deviceRemovedNotification(const QUuid &deviceId) -{ - QVariantMap params; - params.insert("deviceId", deviceId); - emit DeviceRemoved(params); -} - -void DeviceHandler::deviceAddedNotification(Thing *thing) -{ - QVariantMap params; - QVariantMap deviceMap = pack(thing).toMap(); - // Patch in deviceClassId - deviceMap.insert("deviceClassId", deviceMap.value("thingClassId")); - params.insert("device", deviceMap); - emit DeviceAdded(params); -} - -void DeviceHandler::deviceChangedNotification(Thing *thing) -{ - QVariantMap params; - QVariantMap deviceMap = pack(thing).toMap(); - // Patch in deviceClassId - deviceMap.insert("deviceClassId", deviceMap.value("thingClassId")); - params.insert("device", deviceMap); - emit DeviceChanged(params); -} - -void DeviceHandler::deviceSettingChangedNotification(const ThingId &thingId, const ParamTypeId ¶mTypeId, const QVariant &value) -{ - QVariantMap params; - params.insert("deviceId", thingId); - params.insert("paramTypeId", paramTypeId.toString()); - params.insert("value", value); - emit DeviceSettingChanged(params); -} - -QVariantMap DeviceHandler::translateNotification(const QString ¬ification, const QVariantMap ¶ms, const QLocale &locale) -{ - if (notification == "DeviceChanged") { - QVariantMap deviceMap = params.value("device").toMap(); - DeviceId deviceId = params.value("device").toMap().value("id").toUuid(); - Thing *device = NymeaCore::instance()->thingManager()->findConfiguredThing(deviceId); - QString setupDisplayMessage = params.value("device").toMap().value("setupDisplayMessage").toString(); - QString translatedSetupDisplayMessage = NymeaCore::instance()->thingManager()->translate(device->pluginId(), setupDisplayMessage, locale); - if (!translatedSetupDisplayMessage.isEmpty()) { - deviceMap["setupDisplayMessage"] = translatedSetupDisplayMessage; - } - QVariantMap translatedParams = params; - translatedParams["device"] = deviceMap; - return translatedParams; - } - - return params; -} - -QVariantMap DeviceHandler::statusToReply(Thing::ThingError status) const -{ - QVariantMap returns; - returns.insert("deviceError", enumValueName(status).replace("Thing", "Device")); - return returns; -} - -DeviceClass::DeviceClass(const ThingClass &other): - ThingClass(other.pluginId(), other.vendorId(), other.id()) -{ - setName(other.name()); - setBrowsable(other.browsable()); - setEventTypes(other.eventTypes()); - setInterfaces(other.interfaces()); - setParamTypes(other.paramTypes()); - setStateTypes(other.stateTypes()); - setActionTypes(other.actionTypes()); - setDisplayName(other.displayName()); - setSetupMethod(other.setupMethod()); - setCreateMethods(other.createMethods()); - setSettingsTypes(other.settingsTypes()); - setDiscoveryParamTypes(other.discoveryParamTypes()); - setBrowserItemActionTypes(other.browserItemActionTypes()); -} - -DeviceClassId Device::deviceClassId() const -{ - return thingClassId(); -} - -} diff --git a/libnymea-core/jsonrpc/devicehandler.h b/libnymea-core/jsonrpc/devicehandler.h deleted file mode 100644 index fb8c644c..00000000 --- a/libnymea-core/jsonrpc/devicehandler.h +++ /dev/null @@ -1,210 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef DEVICEHANDLER_H -#define DEVICEHANDLER_H - -#include "jsonrpc/jsonhandler.h" -#include "integrations/thingmanager.h" -#include "integrations/thing.h" - -#include - -DECLARE_TYPE_ID(DeviceClass) -DECLARE_TYPE_ID(Device) - -namespace nymeaserver { - -// Device has been renamed to Thing. As we need to keep compatibility with the Devices API for a bit, -// let's create them here - -class DevicePlugin: public IntegrationPlugin -{ - Q_OBJECT -}; - -class DevicePlugins: public IntegrationPlugins -{ - Q_GADGET -}; - -class DeviceClass: public ThingClass -{ - Q_GADGET - -public: - DeviceClass(): ThingClass() {} - DeviceClass(const ThingClass &other); -}; - -class DeviceClasses: public ThingClasses -{ - Q_GADGET -}; - -class Device: public Thing -{ - Q_OBJECT - Q_PROPERTY(QUuid deviceClassId READ deviceClassId) -public: - enum DeviceError { - DeviceErrorNoError, - DeviceErrorPluginNotFound, - DeviceErrorVendorNotFound, - DeviceErrorDeviceNotFound, - DeviceErrorDeviceClassNotFound, - DeviceErrorActionTypeNotFound, - DeviceErrorStateTypeNotFound, - DeviceErrorEventTypeNotFound, - DeviceErrorDeviceDescriptorNotFound, - DeviceErrorMissingParameter, - DeviceErrorInvalidParameter, - DeviceErrorSetupFailed, - DeviceErrorDuplicateUuid, - DeviceErrorCreationMethodNotSupported, - DeviceErrorSetupMethodNotSupported, - DeviceErrorHardwareNotAvailable, - DeviceErrorHardwareFailure, - DeviceErrorAuthenticationFailure, - DeviceErrorDeviceInUse, - DeviceErrorDeviceInRule, - DeviceErrorDeviceIsChild, - DeviceErrorPairingTransactionIdNotFound, - DeviceErrorParameterNotWritable, - DeviceErrorItemNotFound, - DeviceErrorItemNotExecutable, - DeviceErrorUnsupportedFeature, - DeviceErrorTimeout, - }; - Q_ENUM(DeviceError) - - enum DeviceSetupStatus { - DeviceSetupStatusNone, - DeviceSetupStatusInProgress, - DeviceSetupStatusComplete, - DeviceSetupStatusFailed, - }; - Q_ENUM(DeviceSetupStatus) - - DeviceClassId deviceClassId() const; -}; - -class Devices: public Things -{ - Q_GADGET -}; - -class DeviceDescriptor: public ThingDescriptor -{ - Q_GADGET - Q_PROPERTY(QUuid deviceId READ thingId USER true) - Q_PROPERTY(ParamList deviceParams READ params) -}; - -class DeviceDescriptors: public ThingDescriptors -{ - Q_GADGET -}; - -class DeviceHandler : public JsonHandler -{ - Q_OBJECT -public: - explicit DeviceHandler(QObject *parent = nullptr); - - QString name() const override; - QHash cacheHashes() const override; - - QVariantMap translateNotification(const QString ¬ification, const QVariantMap ¶ms, const QLocale &locale) override; - - Q_INVOKABLE JsonReply *GetSupportedVendors(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetSupportedDevices(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetDiscoveredDevices(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetPlugins(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetPluginConfiguration(const QVariantMap ¶ms) const; - Q_INVOKABLE JsonReply *SetPluginConfiguration(const QVariantMap ¶ms); - - Q_INVOKABLE JsonReply *AddConfiguredDevice(const QVariantMap ¶ms, const JsonContext &context); - Q_INVOKABLE JsonReply *PairDevice(const QVariantMap ¶ms, const JsonContext &context); - Q_INVOKABLE JsonReply *ConfirmPairing(const QVariantMap ¶ms, const JsonContext &context); - Q_INVOKABLE JsonReply *GetConfiguredDevices(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *ReconfigureDevice(const QVariantMap ¶ms, const JsonContext &context); - Q_INVOKABLE JsonReply *EditDevice(const QVariantMap ¶ms); - Q_INVOKABLE JsonReply *RemoveConfiguredDevice(const QVariantMap ¶ms); - Q_INVOKABLE JsonReply *SetDeviceSettings(const QVariantMap ¶ms); - - Q_INVOKABLE JsonReply *GetEventTypes(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetActionTypes(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetStateTypes(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetStateValue(const QVariantMap ¶ms) const; - Q_INVOKABLE JsonReply *GetStateValues(const QVariantMap ¶ms) const; - - Q_INVOKABLE JsonReply *BrowseDevice(const QVariantMap ¶ms, const JsonContext &context) const; - Q_INVOKABLE JsonReply *GetBrowserItem(const QVariantMap ¶ms, const JsonContext &context) const; - - Q_INVOKABLE JsonReply *ExecuteAction(const QVariantMap ¶ms, const JsonContext &context); - Q_INVOKABLE JsonReply *ExecuteBrowserItem(const QVariantMap ¶ms, const JsonContext &context); - Q_INVOKABLE JsonReply *ExecuteBrowserItemAction(const QVariantMap ¶ms, const JsonContext &context); - - static QVariantMap packBrowserItem(const BrowserItem &item); - -signals: - void PluginConfigurationChanged(const QVariantMap ¶ms); - void StateChanged(const QVariantMap ¶ms); - void DeviceRemoved(const QVariantMap ¶ms); - void DeviceAdded(const QVariantMap ¶ms); - void DeviceChanged(const QVariantMap ¶ms); - void DeviceSettingChanged(const QVariantMap ¶ms); - void EventTriggered(const QVariantMap ¶ms); - -private slots: - void pluginConfigChanged(const PluginId &id, const ParamList &config); - - void deviceStateChanged(Thing *device, const QUuid &stateTypeId, const QVariant &value); - - void deviceRemovedNotification(const QUuid &deviceId); - - void deviceAddedNotification(Thing *thing); - - void deviceChangedNotification(Thing *thing); - - void deviceSettingChangedNotification(const ThingId &thingId, const ParamTypeId ¶mTypeId, const QVariant &value); - -private: - QVariantMap statusToReply(Device::ThingError status) const; - - QHash m_cacheHashes; -}; - -} -Q_DECLARE_METATYPE(nymeaserver::DeviceClass) -Q_DECLARE_METATYPE(nymeaserver::Device::DeviceError) - -#endif // DEVICEHANDLER_H diff --git a/libnymea-core/jsonrpc/eventhandler.cpp b/libnymea-core/jsonrpc/eventhandler.cpp deleted file mode 100644 index a0cb4c1a..00000000 --- a/libnymea-core/jsonrpc/eventhandler.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "eventhandler.h" -#include "nymeacore.h" -#include "loggingcategories.h" -#include "devicehandler.h" - -namespace nymeaserver { - -/*! Constructs a new \l EventHandler with the given \a parent. */ -EventHandler::EventHandler(QObject *parent) : - JsonHandler(parent) -{ - registerEnum(); - registerEnum(); - // Objects - registerObject(); - registerObject(); - registerObject(); - registerObject(); - - // Methods - QString description; QVariantMap params; QVariantMap returns; - description = "Get the EventType for the given eventTypeId."; - params.insert("eventTypeId", enumValueName(Uuid)); - returns.insert("deviceError", enumRef()); - returns.insert("o:eventType", objectRef()); - registerMethod("GetEventType", description, params, returns, "Please use the Devices namespace instead."); - - // Notifications - params.clear(); returns.clear(); - description = "Emitted whenever an Event is triggered."; - params.insert("event", objectRef()); - registerNotification("EventTriggered", description, params, "Please use Devices.EventTriggered instead."); - connect(NymeaCore::instance(), &NymeaCore::eventTriggered, this, &EventHandler::eventTriggered); -} - -/*! Returns the name of the \l{EventHandler}. In this case \b Events.*/ -QString EventHandler::name() const -{ - return "Events"; -} - -void EventHandler::eventTriggered(const Event &event) -{ - QVariantMap params; - params.insert("event", pack(event)); - emit EventTriggered(params); -} - -JsonReply* EventHandler::GetEventType(const QVariantMap ¶ms, const JsonContext &context) const -{ - qCDebug(dcJsonRpc) << "asked for event type" << params; - EventTypeId eventTypeId(params.value("eventTypeId").toString()); - foreach (const ThingClass &deviceClass, NymeaCore::instance()->thingManager()->supportedThings()) { - foreach (const EventType &eventType, deviceClass.eventTypes()) { - if (eventType.id() == eventTypeId) { - EventType translatedEventType = eventType; - translatedEventType.setDisplayName(NymeaCore::instance()->thingManager()->translate(deviceClass.pluginId(), eventType.displayName(), context.locale())); - QVariantMap data; - data.insert("deviceError", enumValueName(Thing::ThingErrorNoError).replace("ThingError", "DeviceError")); - data.insert("eventType", pack(translatedEventType)); - return createReply(data); - } - } - } - QVariantMap data; - data.insert("deviceError", enumValueName(Thing::ThingErrorEventTypeNotFound).replace("ThingError", "DeviceError")); - return createReply(data); -} - -} diff --git a/libnymea-core/jsonrpc/eventhandler.h b/libnymea-core/jsonrpc/eventhandler.h deleted file mode 100644 index 615ed2b4..00000000 --- a/libnymea-core/jsonrpc/eventhandler.h +++ /dev/null @@ -1,58 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef EVENTHANDLER_H -#define EVENTHANDLER_H - -#include "jsonrpc/jsonhandler.h" - -#include "types/event.h" - -namespace nymeaserver { - -class EventHandler : public JsonHandler -{ - Q_OBJECT -public: - explicit EventHandler(QObject *parent = nullptr); - QString name() const override; - - Q_INVOKABLE JsonReply *GetEventType(const QVariantMap ¶ms, const JsonContext &context) const; - -signals: - void EventTriggered(const QVariantMap ¶ms); - -private slots: - void eventTriggered(const Event &event); -}; - -} - -#endif // EVENTHANDLER_H diff --git a/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp b/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp index 147c460e..8639bf63 100644 --- a/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp +++ b/libnymea-core/jsonrpc/jsonrpcserverimplementation.cpp @@ -60,14 +60,10 @@ #include "version.h" #include "cloud/cloudmanager.h" -#include "devicehandler.h" #include "integrationshandler.h" -#include "actionhandler.h" #include "ruleshandler.h" #include "scriptshandler.h" -#include "eventhandler.h" #include "logginghandler.h" -#include "statehandler.h" #include "configurationhandler.h" #include "networkmanagerhandler.h" #include "tagshandler.h" @@ -587,12 +583,8 @@ void JsonRPCServerImplementation::setup() { registerHandler(this); registerHandler(new IntegrationsHandler(NymeaCore::instance()->thingManager(), this)); - registerHandler(new DeviceHandler(this)); - registerHandler(new ActionHandler(this)); registerHandler(new RulesHandler(this)); - registerHandler(new EventHandler(this)); registerHandler(new LoggingHandler(this)); - registerHandler(new StateHandler(this)); registerHandler(new ConfigurationHandler(this)); registerHandler(new NetworkManagerHandler(NymeaCore::instance()->networkManager(), this)); registerHandler(new TagsHandler(this)); diff --git a/libnymea-core/jsonrpc/logginghandler.cpp b/libnymea-core/jsonrpc/logginghandler.cpp index 88853ff0..d9b89723 100644 --- a/libnymea-core/jsonrpc/logginghandler.cpp +++ b/libnymea-core/jsonrpc/logginghandler.cpp @@ -76,7 +76,6 @@ LoggingHandler::LoggingHandler(QObject *parent) : params.insert("o:eventTypes", QVariantList() << enumRef()); params.insert("o:typeIds", QVariantList() << enumValueName(Uuid)); params.insert("o:thingIds", QVariantList() << enumValueName(Uuid)); - params.insert("d:o:deviceIds", QVariantList() << enumValueName(Uuid)); params.insert("o:values", QVariantList() << enumValueName(Variant)); params.insert("o:limit", enumValueName(Int)); params.insert("o:offset", enumValueName(Int)); @@ -189,7 +188,6 @@ QVariantMap LoggingHandler::packLogEntry(const LogEntry &logEntry) logEntryMap.insert("typeId", logEntry.typeId()); } logEntryMap.insert("thingId", logEntry.thingId()); - logEntryMap.insert("deviceId", logEntry.thingId()); // DEPRECATED logEntryMap.insert("value", LogValueTool::convertVariantToString(logEntry.value())); break; case Logging::LoggingSourceSystem: @@ -251,13 +249,6 @@ LogFilter LoggingHandler::unpackLogFilter(const QVariantMap &logFilterMap) filter.addThingId(ThingId(thingId.toString())); } } - // DEPRECATED - if (logFilterMap.contains("deviceIds")) { - QVariantList deviceIds = logFilterMap.value("deviceIds").toList(); - foreach (const QVariant &deviceId, deviceIds) { - filter.addThingId(ThingId(deviceId.toString())); - } - } if (logFilterMap.contains("values")) { QVariantList values = logFilterMap.value("values").toList(); foreach (const QVariant &value, values) { diff --git a/libnymea-core/jsonrpc/ruleshandler.cpp b/libnymea-core/jsonrpc/ruleshandler.cpp index e6ac1d10..60bceec8 100644 --- a/libnymea-core/jsonrpc/ruleshandler.cpp +++ b/libnymea-core/jsonrpc/ruleshandler.cpp @@ -166,8 +166,7 @@ RulesHandler::RulesHandler(QObject *parent) : params.clear(); returns.clear(); description = "Find a list of rules containing any of the given parameters."; - params.insert("o:thingId", enumValueName(Uuid)); // TODO: remove "o:" from thingId once we drop deviceId support - params.insert("d:o:deviceId", enumValueName(Uuid)); + params.insert("thingId", enumValueName(Uuid)); returns.insert("ruleIds", QVariantList() << enumValueName(Uuid)); registerMethod("FindRules", description, params, returns); @@ -301,10 +300,7 @@ JsonReply* RulesHandler::RemoveRule(const QVariantMap ¶ms) JsonReply *RulesHandler::FindRules(const QVariantMap ¶ms) { - ThingId thingId = ThingId(params.value("deviceId").toString()); // DEPRECATED - if (params.contains("thingId")) { - thingId = ThingId(params.value("thingId").toString()); - } + ThingId thingId = ThingId(params.value("thingId").toString()); QList rules = NymeaCore::instance()->ruleEngine()->findRules(thingId); QVariantList rulesList; diff --git a/libnymea-core/jsonrpc/statehandler.cpp b/libnymea-core/jsonrpc/statehandler.cpp deleted file mode 100644 index b428148b..00000000 --- a/libnymea-core/jsonrpc/statehandler.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -/*! - \class nymeaserver::StateHandler - \brief This subclass of \l{JsonHandler} processes the JSON requests for the \tt States namespace of the JSON-RPC API. - - \ingroup json - \inmodule core - - This \l{JsonHandler} will be created in the \l{JsonRPCServer} and used to handle JSON-RPC requests - for the \tt {States} namespace of the API. - - \sa State, JsonHandler, JsonRPCServer -*/ - -#include "statehandler.h" -#include "nymeacore.h" -#include "loggingcategories.h" - -#include "devicehandler.h" - -namespace nymeaserver { - -/*! Constructs a new \l{StateHandler} with the given \a parent. */ -StateHandler::StateHandler(QObject *parent) : - JsonHandler(parent) -{ - registerEnum(); - registerEnum(); - registerObject(); - registerObject(); - - // Methods - QString description; QVariantMap params; QVariantMap returns; - description = "Get the StateType for the given stateTypeId."; - params.insert("stateTypeId", enumValueName(Uuid)); - returns.insert("deviceError", enumRef()); - returns.insert("o:stateType", objectRef()); - registerMethod("GetStateType", description, params, returns, "Please use the Integrations namespace instead."); -} - -/*! Returns the name of the \l{StateHandler}. In this case \b States.*/ -QString StateHandler::name() const -{ - return "States"; -} - -JsonReply* StateHandler::GetStateType(const QVariantMap ¶ms, const JsonContext &context) const -{ - qCDebug(dcJsonRpc) << "asked for state type" << params; - StateTypeId stateTypeId(params.value("stateTypeId").toString()); - foreach (const ThingClass &deviceClass, NymeaCore::instance()->thingManager()->supportedThings()) { - foreach (const StateType &stateType, deviceClass.stateTypes()) { - if (stateType.id() == stateTypeId) { - QVariantMap data; - data.insert("deviceError", enumValueName(Thing::ThingErrorNoError).replace("ThingError", "DeviceError")); - StateType translatedStateType = stateType; - translatedStateType.setDisplayName(NymeaCore::instance()->thingManager()->translate(deviceClass.pluginId(), stateType.displayName(), context.locale())); - data.insert("stateType", pack(translatedStateType)); - return createReply(data); - } - } - } - QVariantMap data; - data.insert("deviceError", enumValueName(Thing::ThingErrorStateTypeNotFound).replace("ThingError", "DeviceError")); - return createReply(data); -} - -} diff --git a/libnymea-core/jsonrpc/statehandler.h b/libnymea-core/jsonrpc/statehandler.h deleted file mode 100644 index 85f9b1b4..00000000 --- a/libnymea-core/jsonrpc/statehandler.h +++ /dev/null @@ -1,51 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef STATEHANDLER_H -#define STATEHANDLER_H - -#include "jsonrpc/jsonhandler.h" - -namespace nymeaserver { - -class StateHandler : public JsonHandler -{ - Q_OBJECT -public: - explicit StateHandler(QObject *parent = nullptr); - QString name() const override; - - Q_INVOKABLE JsonReply *GetStateType(const QVariantMap ¶ms, const JsonContext &context) const; - -}; - -} - -#endif // EVENTHANDLER_H diff --git a/libnymea-core/jsonrpc/tagshandler.cpp b/libnymea-core/jsonrpc/tagshandler.cpp index 67b40cc1..eff2024d 100644 --- a/libnymea-core/jsonrpc/tagshandler.cpp +++ b/libnymea-core/jsonrpc/tagshandler.cpp @@ -49,7 +49,6 @@ TagsHandler::TagsHandler(QObject *parent) : JsonHandler(parent) "Tags can be filtered by a thingID, a ruleId, an appId, a tagId or a combination of any (however, " "combining thingId and ruleId will return an empty result set)."; params.insert("o:thingId", enumValueName(Uuid)); - params.insert("d:o:deviceId", enumValueName(Uuid)); params.insert("o:ruleId", enumValueName(Uuid)); params.insert("o:appId", enumValueName(String)); params.insert("o:tagId", enumValueName(String)); @@ -108,10 +107,6 @@ JsonReply *TagsHandler::GetTags(const QVariantMap ¶ms) const if (params.contains("thingId") && params.value("thingId").toUuid() != tag.thingId()) { continue; } - if (params.contains("deviceId") && params.value("deviceId").toUuid() != tag.thingId()) { - // nymea < 0.19 - continue; - } if (params.contains("ruleId") && params.value("ruleId").toUuid() != tag.ruleId()) { continue; } diff --git a/libnymea-core/libnymea-core.pro b/libnymea-core/libnymea-core.pro index c4fbbce8..b34da011 100644 --- a/libnymea-core/libnymea-core.pro +++ b/libnymea-core/libnymea-core.pro @@ -103,11 +103,7 @@ HEADERS += nymeacore.h \ jsonrpc/jsonrpcserverimplementation.h \ jsonrpc/jsonvalidator.h \ jsonrpc/integrationshandler.h \ - jsonrpc/devicehandler.h \ jsonrpc/ruleshandler.h \ - jsonrpc/actionhandler.h \ - jsonrpc/eventhandler.h \ - jsonrpc/statehandler.h \ jsonrpc/logginghandler.h \ jsonrpc/configurationhandler.h \ jsonrpc/networkmanagerhandler.h \ @@ -197,11 +193,7 @@ SOURCES += nymeacore.cpp \ jsonrpc/jsonrpcserverimplementation.cpp \ jsonrpc/jsonvalidator.cpp \ jsonrpc/integrationshandler.cpp \ - jsonrpc/devicehandler.cpp \ jsonrpc/ruleshandler.cpp \ - jsonrpc/actionhandler.cpp \ - jsonrpc/eventhandler.cpp \ - jsonrpc/statehandler.cpp \ jsonrpc/logginghandler.cpp \ jsonrpc/configurationhandler.cpp \ jsonrpc/networkmanagerhandler.cpp \ diff --git a/libnymea-core/logging/logentry.h b/libnymea-core/logging/logentry.h index fcab8452..fdf49db0 100644 --- a/libnymea-core/logging/logentry.h +++ b/libnymea-core/logging/logentry.h @@ -48,7 +48,6 @@ class LogEntry Q_PROPERTY(Logging::LoggingSource source READ source) Q_PROPERTY(QUuid typeId READ typeId USER true) Q_PROPERTY(QUuid thingId READ thingId USER true) - Q_PROPERTY(QUuid deviceId READ thingId USER true REVISION 1) Q_PROPERTY(QVariant value READ value USER true) Q_PROPERTY(bool active READ active USER true) Q_PROPERTY(Logging::LoggingEventType eventType READ eventType USER true) diff --git a/libnymea-core/ruleengine/ruleaction.h b/libnymea-core/ruleengine/ruleaction.h index 017a05ab..d5d2ff9f 100644 --- a/libnymea-core/ruleengine/ruleaction.h +++ b/libnymea-core/ruleengine/ruleaction.h @@ -40,7 +40,6 @@ class LIBNYMEA_EXPORT RuleAction { Q_GADGET Q_PROPERTY(QUuid thingId READ thingId WRITE setThingId USER true) - Q_PROPERTY(QUuid deviceId READ thingId WRITE setThingId USER true REVISION 1) Q_PROPERTY(QUuid actionTypeId READ actionTypeId WRITE setActionTypeId USER true) Q_PROPERTY(QString interface READ interface WRITE setInterface USER true) Q_PROPERTY(QString interfaceAction READ interfaceAction WRITE setInterfaceAction USER true) diff --git a/libnymea-core/ruleengine/ruleactionparam.h b/libnymea-core/ruleengine/ruleactionparam.h index 7925f6a3..c5ef4d4a 100644 --- a/libnymea-core/ruleengine/ruleactionparam.h +++ b/libnymea-core/ruleengine/ruleactionparam.h @@ -48,7 +48,6 @@ class LIBNYMEA_EXPORT RuleActionParam Q_PROPERTY(QUuid eventTypeId READ eventTypeId WRITE setEventTypeId USER true) Q_PROPERTY(QUuid eventParamTypeId READ eventParamTypeId WRITE setEventParamTypeId USER true) Q_PROPERTY(QUuid stateThingId READ stateThingId WRITE setStateThingId USER true) - Q_PROPERTY(QUuid stateDeviceId READ stateThingId WRITE setStateThingId USER true REVISION 1) Q_PROPERTY(QUuid stateTypeId READ stateTypeId WRITE setStateTypeId USER true) public: diff --git a/libnymea-core/scriptengine/scriptengine.cpp b/libnymea-core/scriptengine/scriptengine.cpp index 6cc806b5..a11645c7 100644 --- a/libnymea-core/scriptengine/scriptengine.cpp +++ b/libnymea-core/scriptengine/scriptengine.cpp @@ -57,12 +57,9 @@ QtMessageHandler ScriptEngine::s_upstreamMessageHandler; QLoggingCategory::CategoryFilter ScriptEngine::s_oldCategoryFilter = nullptr; QMutex ScriptEngine::s_loggerMutex; -ScriptEngine::ScriptEngine(ThingManager *deviceManager, QObject *parent) : QObject(parent), - m_deviceManager(deviceManager) +ScriptEngine::ScriptEngine(ThingManager *thingManager, QObject *parent) : QObject(parent), + m_thingManager(thingManager) { - qmlRegisterType("nymea", 1, 0, "DeviceEvent"); - qmlRegisterType("nymea", 1, 0, "DeviceAction"); - qmlRegisterType("nymea", 1, 0, "DeviceState"); qmlRegisterType("nymea", 1, 0, "ThingEvent"); qmlRegisterType("nymea", 1, 0, "ThingAction"); qmlRegisterType("nymea", 1, 0, "ThingState"); @@ -71,7 +68,7 @@ ScriptEngine::ScriptEngine(ThingManager *deviceManager, QObject *parent) : QObje qmlRegisterType("nymea", 1, 0, "Alarm"); m_engine = new QQmlEngine(this); - m_engine->setProperty("thingManager", reinterpret_cast(m_deviceManager)); + m_engine->setProperty("thingManager", reinterpret_cast(m_thingManager)); // Don't automatically print script warnings (that is, runtime errors, *not* console.warn() messages) // to stdout as they'd end up on the "default" logging category. diff --git a/libnymea-core/scriptengine/scriptengine.h b/libnymea-core/scriptengine/scriptengine.h index e60532b9..8e3017d1 100644 --- a/libnymea-core/scriptengine/scriptengine.h +++ b/libnymea-core/scriptengine/scriptengine.h @@ -75,7 +75,7 @@ public: QByteArray content; }; - explicit ScriptEngine(ThingManager *deviceManager, QObject *parent = nullptr); + explicit ScriptEngine(ThingManager *thingManager, QObject *parent = nullptr); ~ScriptEngine(); Scripts scripts(); @@ -102,7 +102,7 @@ private: void onScriptMessage(QtMsgType type, const QMessageLogContext &context, const QString &message); private: - ThingManager *m_deviceManager = nullptr; + ThingManager *m_thingManager = nullptr; QQmlEngine *m_engine = nullptr; QHash m_scripts; diff --git a/libnymea-core/tagging/tag.h b/libnymea-core/tagging/tag.h index d1bff37c..0abfb229 100644 --- a/libnymea-core/tagging/tag.h +++ b/libnymea-core/tagging/tag.h @@ -44,7 +44,6 @@ class Tag Q_PROPERTY(QString appId READ appId WRITE setAppId) Q_PROPERTY(QString tagId READ tagId WRITE setTagId) Q_PROPERTY(QUuid thingId READ thingId WRITE setThingId USER true) - Q_PROPERTY(QUuid deviceId READ thingId WRITE setThingId USER true REVISION 1) Q_PROPERTY(QUuid ruleId READ ruleId WRITE setRuleId USER true) Q_PROPERTY(QString value READ value WRITE setValue USER true) public: diff --git a/libnymea/integrations/thingdescriptor.h b/libnymea/integrations/thingdescriptor.h index f24b4c78..02892c61 100644 --- a/libnymea/integrations/thingdescriptor.h +++ b/libnymea/integrations/thingdescriptor.h @@ -45,7 +45,6 @@ class LIBNYMEA_EXPORT ThingDescriptor Q_PROPERTY(QUuid thingId READ thingId USER true) Q_PROPERTY(QString title READ title) Q_PROPERTY(QString description READ description) - Q_PROPERTY(ParamList deviceParams READ params REVISION 1) // Had been forgotten in the device->thing transition. Q_PROPERTY(ParamList params READ params) // added in 0.27 public: diff --git a/libnymea/types/action.h b/libnymea/types/action.h index 042a34e9..29f70359 100644 --- a/libnymea/types/action.h +++ b/libnymea/types/action.h @@ -42,7 +42,6 @@ class LIBNYMEA_EXPORT Action Q_GADGET Q_PROPERTY(QUuid actionTypeId READ actionTypeId WRITE setActionTypeId) Q_PROPERTY(QUuid thingId READ thingId WRITE setThingId) - Q_PROPERTY(QUuid deviceId READ thingId WRITE setThingId REVISION 1) Q_PROPERTY(ParamList params READ params WRITE setParams USER true) public: diff --git a/libnymea/types/event.h b/libnymea/types/event.h index 62ee3d33..26eb1f8d 100644 --- a/libnymea/types/event.h +++ b/libnymea/types/event.h @@ -44,7 +44,6 @@ class LIBNYMEA_EXPORT Event Q_GADGET Q_PROPERTY(QUuid eventTypeId READ eventTypeId) Q_PROPERTY(QUuid thingId READ thingId) - Q_PROPERTY(QUuid deviceId READ thingId REVISION 1) Q_PROPERTY(ParamList params READ params) public: Event(); diff --git a/libnymea/types/eventdescriptor.h b/libnymea/types/eventdescriptor.h index af23e07e..dcdfb041 100644 --- a/libnymea/types/eventdescriptor.h +++ b/libnymea/types/eventdescriptor.h @@ -44,7 +44,6 @@ class LIBNYMEA_EXPORT EventDescriptor { Q_GADGET Q_PROPERTY(QUuid thingId READ thingId WRITE setThingId USER true) - Q_PROPERTY(QUuid deviceId READ thingId WRITE setThingId USER true REVISION 1) Q_PROPERTY(QUuid eventTypeId READ eventTypeId WRITE setEventTypeId USER true) Q_PROPERTY(QString interface READ interface WRITE setInterface USER true) Q_PROPERTY(QString interfaceEvent READ interfaceEvent WRITE setInterfaceEvent USER true) diff --git a/libnymea/types/statedescriptor.h b/libnymea/types/statedescriptor.h index 7f608bc1..0b30a1df 100644 --- a/libnymea/types/statedescriptor.h +++ b/libnymea/types/statedescriptor.h @@ -46,7 +46,6 @@ class LIBNYMEA_EXPORT StateDescriptor Q_GADGET Q_PROPERTY(QUuid stateTypeId READ stateTypeId WRITE setStateTypeId USER true) Q_PROPERTY(QUuid thingId READ thingId WRITE setThingId USER true) - Q_PROPERTY(QUuid deviceId READ thingId WRITE setThingId USER true REVISION 1) Q_PROPERTY(QString interface READ interface WRITE setInterface USER true) Q_PROPERTY(QString interfaceState READ interfaceState WRITE setInterfaceState USER true) Q_PROPERTY(QVariant value READ stateValue WRITE setStateValue USER true) diff --git a/nymea.pro b/nymea.pro index 87383251..918fef97 100644 --- a/nymea.pro +++ b/nymea.pro @@ -4,8 +4,8 @@ include(nymea.pri) NYMEA_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"') # define protocol versions -JSON_PROTOCOL_VERSION_MAJOR=5 -JSON_PROTOCOL_VERSION_MINOR=8 +JSON_PROTOCOL_VERSION_MAJOR=6 +JSON_PROTOCOL_VERSION_MINOR=0 JSON_PROTOCOL_VERSION="$${JSON_PROTOCOL_VERSION_MAJOR}.$${JSON_PROTOCOL_VERSION_MINOR}" LIBNYMEA_API_VERSION_MAJOR=7 LIBNYMEA_API_VERSION_MINOR=3 diff --git a/tests/auto/actions/actions.pro b/tests/auto/actions/actions.pro deleted file mode 100644 index 8cf10580..00000000 --- a/tests/auto/actions/actions.pro +++ /dev/null @@ -1,6 +0,0 @@ -TARGET = testactions - -include(../../../nymea.pri) -include(../autotests.pri) - -SOURCES += testactions.cpp diff --git a/tests/auto/actions/testactions.cpp b/tests/auto/actions/testactions.cpp deleted file mode 100644 index 2cc576fb..00000000 --- a/tests/auto/actions/testactions.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "nymeatestbase.h" -#include "integrations/thing.h" -#include "jsonrpc/devicehandler.h" - -using namespace nymeaserver; - -class TestActions: public NymeaTestBase -{ - Q_OBJECT - -private slots: - void executeAction_data(); - void executeAction(); - - void getActionType_data(); - void getActionType(); - -}; - -void TestActions::executeAction_data() -{ - QTest::addColumn("deviceId"); - QTest::addColumn("actionTypeId"); - QTest::addColumn("actionParams"); - QTest::addColumn("error"); - - QVariantList params; - QVariantMap param1; - param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId); - param1.insert("value", 5); - params.append(param1); - QVariantMap param2; - param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId); - param2.insert("value", true); - params.append(param2); - - QTest::newRow("valid action") << m_mockThingId << mockWithParamsActionTypeId << params << Device::DeviceErrorNoError; - QTest::newRow("invalid deviceId") << ThingId::createThingId() << mockWithParamsActionTypeId << params << Device::DeviceErrorDeviceNotFound; - QTest::newRow("invalid actionTypeId") << m_mockThingId << ActionTypeId::createActionTypeId() << params << Device::DeviceErrorActionTypeNotFound; - QTest::newRow("missing params") << m_mockThingId << mockWithParamsActionTypeId << QVariantList() << Device::DeviceErrorMissingParameter; - QTest::newRow("async action") << m_mockThingId << mockAsyncActionTypeId << QVariantList() << Device::DeviceErrorNoError; - QTest::newRow("broken action") << m_mockThingId << mockFailingActionTypeId << QVariantList() << Device::DeviceErrorSetupFailed; - QTest::newRow("async broken action") << m_mockThingId << mockAsyncFailingActionTypeId << QVariantList() << Device::DeviceErrorSetupFailed; -} - -void TestActions::executeAction() -{ - QFETCH(ThingId, deviceId); - QFETCH(ActionTypeId, actionTypeId); - QFETCH(QVariantList, actionParams); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("actionTypeId", actionTypeId); - params.insert("deviceId", deviceId); - params.insert("params", actionParams); - QVariant response = injectAndWait("Actions.ExecuteAction", params); - verifyError(response, "deviceError", enumValueName(error)); - - // Fetch action execution history from mock device - QNetworkAccessManager nam; - QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); - - QNetworkRequest request(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockThing1Port))); - QNetworkReply *reply = nam.get(request); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - QByteArray data = reply->readAll(); - - if (error == Device::DeviceErrorNoError) { - QVERIFY2(actionTypeId == ActionTypeId(data), QString("ActionTypeId mismatch. Got %1, Expected: %2") - .arg(ActionTypeId(data).toString()).arg(actionTypeId.toString()).toLatin1().data()); - } else { - QVERIFY2(data.length() == 0, QString("Data is %1, should be empty.").arg(QString(data)).toLatin1().data()); - } - - // cleanup for the next run - spy.clear(); - request.setUrl(QUrl(QString("http://localhost:%1/clearactionhistory").arg(m_mockThing1Port))); - reply = nam.get(request); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - - spy.clear(); - request.setUrl(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockThing1Port))); - reply = nam.get(request); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - data = reply->readAll(); - qDebug() << "cleared data:" << data; - -} - -void TestActions::getActionType_data() -{ - QTest::addColumn("actionTypeId"); - QTest::addColumn("error"); - - QTest::newRow("valid actiontypeid") << mockWithParamsActionTypeId << Device::DeviceErrorNoError; - QTest::newRow("invalid actiontypeid") << ActionTypeId::createActionTypeId() << Device::DeviceErrorActionTypeNotFound; -} - -void TestActions::getActionType() -{ - QFETCH(ActionTypeId, actionTypeId); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("actionTypeId", actionTypeId.toString()); - QVariant response = injectAndWait("Actions.GetActionType", params); - - verifyError(response, "deviceError", enumValueName(error)); - - if (error == Device::DeviceErrorNoError) { - QVERIFY2(ActionTypeId(response.toMap().value("params").toMap().value("actionType").toMap().value("id").toString()) == actionTypeId, "Didn't get a reply for the same actionTypeId as requested."); - } -} - -#include "testactions.moc" -QTEST_MAIN(TestActions) diff --git a/tests/auto/api.json b/tests/auto/api.json index 90ce58b8..4c3eafb4 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -1,4 +1,4 @@ -5.8 +6.0 { "enums": { "BasicType": [ @@ -47,41 +47,6 @@ "CreateMethodAuto", "CreateMethodDiscovery" ], - "DeviceError": [ - "DeviceErrorNoError", - "DeviceErrorPluginNotFound", - "DeviceErrorVendorNotFound", - "DeviceErrorDeviceNotFound", - "DeviceErrorDeviceClassNotFound", - "DeviceErrorActionTypeNotFound", - "DeviceErrorStateTypeNotFound", - "DeviceErrorEventTypeNotFound", - "DeviceErrorDeviceDescriptorNotFound", - "DeviceErrorMissingParameter", - "DeviceErrorInvalidParameter", - "DeviceErrorSetupFailed", - "DeviceErrorDuplicateUuid", - "DeviceErrorCreationMethodNotSupported", - "DeviceErrorSetupMethodNotSupported", - "DeviceErrorHardwareNotAvailable", - "DeviceErrorHardwareFailure", - "DeviceErrorAuthenticationFailure", - "DeviceErrorDeviceInUse", - "DeviceErrorDeviceInRule", - "DeviceErrorDeviceIsChild", - "DeviceErrorPairingTransactionIdNotFound", - "DeviceErrorParameterNotWritable", - "DeviceErrorItemNotFound", - "DeviceErrorItemNotExecutable", - "DeviceErrorUnsupportedFeature", - "DeviceErrorTimeout" - ], - "DeviceSetupStatus": [ - "DeviceSetupStatusNone", - "DeviceSetupStatusInProgress", - "DeviceSetupStatusComplete", - "DeviceSetupStatusFailed" - ], "IOType": [ "IOTypeNone", "IOTypeDigitalInput", @@ -441,54 +406,6 @@ ] }, "methods": { - "Actions.ExecuteAction": { - "deprecated": "Please use Integrations.ExecuteAction instead.", - "description": "Execute a single action.", - "params": { - "actionTypeId": "Uuid", - "deviceId": "Uuid", - "o:params": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:displayMessage": "String" - } - }, - "Actions.ExecuteBrowserItem": { - "deprecated": "Please use Integrations.ExecuteBrowserItem instead.", - "description": "Execute the item identified by itemId on the given device.", - "params": { - "deviceId": "Uuid", - "itemId": "String" - }, - "returns": { - "deviceError": "$ref:DeviceError" - } - }, - "Actions.ExecuteBrowserItemAction": { - "deprecated": "Please use Integrations.ExecuteBrowserItem instead.", - "description": "Execute the action for the browser item identified by actionTypeId and the itemId on the given device.", - "params": { - "actionTypeId": "Uuid", - "deviceId": "Uuid", - "itemId": "String", - "o:params": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError" - } - }, - "Actions.GetActionType": { - "deprecated": "Please use the Integrations namespace instead.", - "description": "Get the ActionType for the given ActionTypeId.", - "params": { - "actionTypeId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:actionType": "$ref:ActionType" - } - }, "AppData.Load": { "description": "Retrieve an app data storage value that has previously been set with Store(). If no value had been set for this appId/key combination before, an empty value will be returned.", "params": { @@ -717,289 +634,6 @@ "configurationError": "$ref:ConfigurationError" } }, - "Devices.AddConfiguredDevice": { - "description": "Add a configured device with a setupMethod of SetupMethodJustAdd. For devices with a setupMethod different than SetupMethodJustAdd, use PairDevice. Devices with CreateMethodJustAdd require all parameters to be supplied here. Devices with CreateMethodDiscovery require the use of a deviceDescriptorId. For discovered devices params are not required and will be taken from the DeviceDescriptor, however, they may be overridden by supplying deviceParams.", - "params": { - "deviceClassId": "Uuid", - "name": "String", - "o:deviceDescriptorId": "Uuid", - "o:deviceParams": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:deviceId": "Uuid", - "o:displayMessage": "String" - } - }, - "Devices.BrowseDevice": { - "description": "Browse a device. If a DeviceClass indicates a device is browsable, this method will return the BrowserItems. If no parameter besides the deviceId is used, the root node of this device will be returned. Any returned item which is browsable can be passed as node. Results will be children of the given node.\nIn case of an error during browsing, the error will be indicated and the displayMessage may contain additional information for the user. The displayMessage will be translated. A client UI showing this message to the user should be prepared for empty, but also longer strings.", - "params": { - "deviceId": "Uuid", - "o:itemId": "String" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "items": [ - "$ref:BrowserItem" - ], - "o:displayMessage": "String" - } - }, - "Devices.ConfirmPairing": { - "description": "Confirm an ongoing pairing. For SetupMethodUserAndPassword, provide the username in the \"username\" field and the password in the \"secret\" field. For SetupMethodEnterPin and provide the PIN in the \"secret\" field. In case of SetupMethodOAuth, the previously opened web view will eventually be redirected to http://128.0.0.1:8888 and the OAuth code as query parameters to this url. Provide the entire unmodified URL in the secret field.", - "params": { - "o:secret": "String", - "o:username": "String", - "pairingTransactionId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:deviceId": "Uuid", - "o:displayMessage": "String" - } - }, - "Devices.EditDevice": { - "description": "Edit the name of a device. This method does not change the configuration of the device.", - "params": { - "deviceId": "Uuid", - "name": "String" - }, - "returns": { - "deviceError": "$ref:DeviceError" - } - }, - "Devices.ExecuteAction": { - "description": "Execute a single action.", - "params": { - "actionTypeId": "Uuid", - "deviceId": "Uuid", - "o:params": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:displayMessage": "String" - } - }, - "Devices.ExecuteBrowserItem": { - "description": "Execute the item identified by itemId on the given device.\nIn case of an error during execution, the error will be indicated and the displayMessage may contain additional information for the user. The displayMessage will be translated. A client UI showing this message to the user should be prepared for empty, but also longer strings.", - "params": { - "deviceId": "Uuid", - "itemId": "String" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:displayMessage": "String" - } - }, - "Devices.ExecuteBrowserItemAction": { - "description": "Execute the action for the browser item identified by actionTypeId and the itemId on the given device.\nIn case of an error during execution, the error will be indicated and the displayMessage may contain additional information for the user. The displayMessage will be translated. A client UI showing this message to the user should be prepared for empty, but also longer strings.", - "params": { - "actionTypeId": "Uuid", - "deviceId": "Uuid", - "itemId": "String", - "o:params": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:displayMessage": "String" - } - }, - "Devices.GetActionTypes": { - "description": "Get action types for a specified deviceClassId.", - "params": { - "deviceClassId": "Uuid" - }, - "returns": { - "actionTypes": "$ref:ActionTypes" - } - }, - "Devices.GetBrowserItem": { - "description": "Get a single item from the browser. This won't give any more info on an item than a regular browseDevice call, but it allows to fetch details of an item if only the ID is known.\nIn case of an error during browsing, the error will be indicated and the displayMessage may contain additional information for the user. The displayMessage will be translated. A client UI showing this message to the user should be prepared for empty, but also longer strings.", - "params": { - "deviceId": "Uuid", - "o:itemId": "String" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:displayMessage": "String", - "o:item": "$ref:BrowserItem" - } - }, - "Devices.GetConfiguredDevices": { - "description": "Returns a list of configured devices, optionally filtered by deviceId.", - "params": { - "o:deviceId": "Uuid" - }, - "returns": { - "devices": "$ref:Devices" - } - }, - "Devices.GetDiscoveredDevices": { - "description": "Performs a device discovery and returns the results. This function may take a while to return. Note that this method will include all the found devices, that is, including devices that already have been added. Those devices will have deviceId set to the device id of the already added device. Such results may be used to reconfigure existing devices and might be filtered in cases where only unknown devices are of interest.", - "params": { - "deviceClassId": "Uuid", - "o:discoveryParams": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:deviceDescriptors": "$ref:DeviceDescriptors", - "o:displayMessage": "String" - } - }, - "Devices.GetEventTypes": { - "description": "Get event types for a specified deviceClassId.", - "params": { - "deviceClassId": "Uuid" - }, - "returns": { - "eventTypes": "$ref:EventTypes" - } - }, - "Devices.GetPluginConfiguration": { - "description": "Get a plugin's params.", - "params": { - "pluginId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:configuration": "$ref:ParamList" - } - }, - "Devices.GetPlugins": { - "description": "Returns a list of loaded plugins.", - "params": { - }, - "returns": { - "plugins": "$ref:DevicePlugins" - } - }, - "Devices.GetStateTypes": { - "description": "Get state types for a specified deviceClassId.", - "params": { - "deviceClassId": "Uuid" - }, - "returns": { - "stateTypes": "$ref:StateTypes" - } - }, - "Devices.GetStateValue": { - "description": "Get the value of the given device and the given stateType", - "params": { - "deviceId": "Uuid", - "stateTypeId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:value": "Variant" - } - }, - "Devices.GetStateValues": { - "description": "Get all the state values of the given device.", - "params": { - "deviceId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:values": "$ref:States" - } - }, - "Devices.GetSupportedDevices": { - "description": "Returns a list of supported Device classes, optionally filtered by vendorId.", - "params": { - "o:vendorId": "Uuid" - }, - "returns": { - "deviceClasses": "$ref:DeviceClasses" - } - }, - "Devices.GetSupportedVendors": { - "description": "Returns a list of supported Vendors.", - "params": { - }, - "returns": { - "vendors": "$ref:Vendors" - } - }, - "Devices.PairDevice": { - "description": "Pair a device. Use this to set up or reconfigure devices for DeviceClasses with a setupMethod different than SetupMethodJustAdd. Depending on the CreateMethod and whether a new devices is set up or an existing one is reconfigured, different parameters are required:\nCreateMethodJustAdd takes the deviceClassId and the parameters to be used with that device. If an existing device should be reconfigured, the deviceId of said device should be given additionally.\nCreateMethodDiscovery requires the use of a deviceDescriptorId, previously obtained with DiscoverDevices. Optionally, parameters can be overridden with the give deviceParams. DeviceDescriptors containing a deviceId will reconfigure that device, descriptors without deviceId will add a new one.\nIf success is true, the return values will contain a pairingTransactionId, a displayMessage and the setupMethod. Depending on the setupMethod, the application should present the use an appropriate login mask, that is, For SetupMethodDisplayPin the user should enter a pin that is displayed on the device, for SetupMethodEnterPin the application should present the given PIN so the user can enter it on the device. For SetupMethodPushButton, the displayMessage shall be presented to the user as informational hints to press a button on the device. For SetupMethodUserAndPassword a login mask for a user and password login should be presented to the user. In case of SetupMethodOAuth, an OAuth URL will be returned which shall be opened in a web view to allow the user logging in.\nOnce the login procedure has completed, the application shall proceed with ConfirmPairing, providing the results of the pairing procedure.", - "params": { - "o:deviceClassId": "Uuid", - "o:deviceDescriptorId": "Uuid", - "o:deviceId": "Uuid", - "o:deviceParams": "$ref:ParamList", - "o:name": "String" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:displayMessage": "String", - "o:oAuthUrl": "String", - "o:pairingTransactionId": "Uuid", - "o:pin": "String", - "o:setupMethod": "$ref:SetupMethod" - } - }, - "Devices.ReconfigureDevice": { - "description": "Reconfigure a device. This comes down to removing and recreating a device with new parameters but keeping its device id the same (and with that keeping rules, tags etc). For devices with create method CreateMethodDiscovery, a discovery (GetDiscoveredDevices) shall be performed first and this method is to be called with a deviceDescriptorId of the re-discovered device instead of the deviceId directly. Device parameters will be taken from the discovery, but can be overridden individually here by providing them in the deviceParams parameter. Only writable parameters can be changed.", - "params": { - "o:deviceDescriptorId": "Uuid", - "o:deviceId": "Uuid", - "o:deviceParams": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:displayMessage": "String" - } - }, - "Devices.RemoveConfiguredDevice": { - "description": "Remove a device from the system.", - "params": { - "deviceId": "Uuid", - "o:removePolicy": "$ref:RemovePolicy", - "o:removePolicyList": [ - { - "policy": "$ref:RemovePolicy", - "ruleId": "Uuid" - } - ] - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:ruleIds": [ - "Uuid" - ] - } - }, - "Devices.SetDeviceSettings": { - "description": "Change the settings of a device.", - "params": { - "deviceId": "Uuid", - "settings": "$ref:ParamList" - }, - "returns": { - "deviceError": "$ref:DeviceError" - } - }, - "Devices.SetPluginConfiguration": { - "description": "Set a plugin's params.", - "params": { - "configuration": "$ref:ParamList", - "pluginId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError" - } - }, - "Events.GetEventType": { - "deprecated": "Please use the Devices namespace instead.", - "description": "Get the EventType for the given eventTypeId.", - "params": { - "eventTypeId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:eventType": "$ref:EventType" - } - }, "Integrations.AddThing": { "description": "Add a new thing to the system. Only things with a setupMethod of SetupMethodJustAdd can be added this way. For things with a setupMethod different than SetupMethodJustAdd, use PairThing. Things with CreateMethodJustAdd require all parameters to be supplied here. Things with CreateMethodDiscovery require the use of a thingDescriptorId. For discovered things, params are not required and will be taken from the ThingDescriptor, however, they may be overridden by supplying thingParams.", "params": { @@ -1489,9 +1123,6 @@ "Logging.GetLogEntries": { "description": "Get the LogEntries matching the given filter. The result set will contain entries matching all filter rules combined. If multiple options are given for a single filter type, the result set will contain entries matching any of those. The offset starts at the newest entry in the result set. By default all items are returned. Example: If the specified filter returns a total amount of 100 entries:\n- a offset value of 10 would include the oldest 90 entries\n- a offset value of 0 would return all 100 entries\n\nThe offset is particularly useful in combination with the maxCount property and can be used for pagination. E.g. A result set of 10000 entries can be fetched in batches of 1000 entries by fetching\n1) offset 0, maxCount 1000: Entries 0 to 9999\n2) offset 10000, maxCount 1000: Entries 10000 - 19999\n3) offset 20000, maxCount 1000: Entries 20000 - 29999\n...", "params": { - "d:o:deviceIds": [ - "Uuid" - ], "o:eventTypes": [ "$ref:LoggingEventType" ], @@ -1769,8 +1400,7 @@ "Rules.FindRules": { "description": "Find a list of rules containing any of the given parameters.", "params": { - "d:o:deviceId": "Uuid", - "o:thingId": "Uuid" + "thingId": "Uuid" }, "returns": { "ruleIds": [ @@ -1858,17 +1488,6 @@ "scriptError": "$ref:ScriptError" } }, - "States.GetStateType": { - "deprecated": "Please use the Integrations namespace instead.", - "description": "Get the StateType for the given stateTypeId.", - "params": { - "stateTypeId": "Uuid" - }, - "returns": { - "deviceError": "$ref:DeviceError", - "o:stateType": "$ref:StateType" - } - }, "System.CheckForUpdates": { "description": "Instruct the system to poll the server for updates. Normally the system should automatically do this in regular intervals, however, if the client wants to allow the user to manually check for new updates now, this can be called. Returns true if the operation has been started successfully and the update manager will become busy. In order to know whether there are updates available, clients should walk through the list of packages retrieved from GetPackages and check whether there are packages with the updateAvailable flag set to true.", "params": { @@ -2029,7 +1648,6 @@ "Tags.GetTags": { "description": "Get the Tags matching the given filter. Tags can be filtered by a thingID, a ruleId, an appId, a tagId or a combination of any (however, combining thingId and ruleId will return an empty result set).", "params": { - "d:o:deviceId": "Uuid", "o:appId": "String", "o:ruleId": "Uuid", "o:tagId": "String", @@ -2307,60 +1925,6 @@ "id": "String" } }, - "Devices.DeviceAdded": { - "description": "Emitted whenever a Device was added.", - "params": { - "device": "$ref:Device" - } - }, - "Devices.DeviceChanged": { - "description": "Emitted whenever the params, name or setupStatus of a Device changes.", - "params": { - "device": "$ref:Device" - } - }, - "Devices.DeviceRemoved": { - "description": "Emitted whenever a Device was removed.", - "params": { - "deviceId": "Uuid" - } - }, - "Devices.DeviceSettingChanged": { - "description": "Emitted whenever the setting of a Device is changed.", - "params": { - "deviceId": "Uuid", - "paramTypeId": "Uuid", - "value": "Variant" - } - }, - "Devices.EventTriggered": { - "description": "Emitted whenever an Event is triggered.", - "params": { - "event": "$ref:Event" - } - }, - "Devices.PluginConfigurationChanged": { - "description": "Emitted whenever a plugin's configuration is changed.", - "params": { - "configuration": "$ref:ParamList", - "pluginId": "Uuid" - } - }, - "Devices.StateChanged": { - "description": "Emitted whenever a State of a device changes.", - "params": { - "deviceId": "Uuid", - "stateTypeId": "Uuid", - "value": "Variant" - } - }, - "Events.EventTriggered": { - "deprecated": "Please use Devices.EventTriggered instead.", - "description": "Emitted whenever an Event is triggered.", - "params": { - "event": "$ref:Event" - } - }, "Integrations.EventTriggered": { "description": "Emitted whenever an Event is triggered.", "params": { @@ -2723,7 +2287,6 @@ "types": { "Action": { "actionTypeId": "Uuid", - "d:deviceId": "Uuid", "o:params": "$ref:ParamList", "thingId": "Uuid" }, @@ -2764,79 +2327,12 @@ "CalendarItems": [ "$ref:CalendarItem" ], - "Device": { - "d:r:setupComplete": "Bool", - "o:name": "String", - "o:settings": "$ref:ParamList", - "r:deviceClassId": "Uuid", - "r:id": "Uuid", - "r:o:loggedEventTypeIds": [ - "Uuid" - ], - "r:o:parentId": "Uuid", - "r:o:setupDisplayMessage": "String", - "r:params": "$ref:ParamList", - "r:setupError": "$ref:ThingError", - "r:setupStatus": "$ref:ThingSetupStatus", - "r:states": "$ref:States", - "r:thingClassId": "Uuid" - }, - "DeviceClass": { - "r:actionTypes": "$ref:ActionTypes", - "r:browsable": "Bool", - "r:browserItemActionTypes": "$ref:ActionTypes", - "r:createMethods": "$ref:CreateMethods", - "r:discoveryParamTypes": "$ref:ParamTypes", - "r:displayName": "String", - "r:eventTypes": "$ref:EventTypes", - "r:id": "Uuid", - "r:interfaces": "StringList", - "r:name": "String", - "r:paramTypes": "$ref:ParamTypes", - "r:pluginId": "Uuid", - "r:providedInterfaces": "StringList", - "r:settingsTypes": "$ref:ParamTypes", - "r:setupMethod": "$ref:SetupMethod", - "r:stateTypes": "$ref:StateTypes", - "r:vendorId": "Uuid" - }, - "DeviceClasses": [ - "$ref:DeviceClass" - ], - "DeviceDescriptor": { - "d:r:deviceParams": "$ref:ParamList", - "r:description": "String", - "r:deviceParams": "$ref:ParamList", - "r:id": "Uuid", - "r:o:deviceId": "Uuid", - "r:o:thingId": "Uuid", - "r:params": "$ref:ParamList", - "r:thingClassId": "Uuid", - "r:title": "String" - }, - "DeviceDescriptors": [ - "$ref:DeviceDescriptor" - ], - "DevicePlugin": { - "r:displayName": "String", - "r:id": "Uuid", - "r:name": "String", - "r:paramTypes": "$ref:ParamTypes" - }, - "DevicePlugins": [ - "$ref:DevicePlugin" - ], - "Devices": [ - "$ref:Device" - ], "Event": { - "d:r:deviceId": "Uuid", "r:eventTypeId": "Uuid", "r:params": "$ref:ParamList", "r:thingId": "Uuid" }, "EventDescriptor": { - "d:o:deviceId": "Uuid", "o:eventTypeId": "Uuid", "o:interface": "String", "o:interfaceEvent": "String", @@ -2884,7 +2380,6 @@ "$ref:LogEntry" ], "LogEntry": { - "d:r:o:deviceId": "Uuid", "r:loggingLevel": "$ref:LoggingLevel", "r:o:active": "Bool", "r:o:errorCode": "String", @@ -2992,7 +2487,6 @@ "r:id": "Uuid" }, "RuleAction": { - "d:o:deviceId": "Uuid", "o:actionTypeId": "Uuid", "o:browserItemId": "String", "o:interface": "String", @@ -3001,7 +2495,6 @@ "o:thingId": "Uuid" }, "RuleActionParam": { - "d:o:stateDeviceId": "Uuid", "o:eventParamTypeId": "Uuid", "o:eventTypeId": "Uuid", "o:paramName": "String", @@ -3057,7 +2550,6 @@ "r:value": "Variant" }, "StateDescriptor": { - "d:o:deviceId": "Uuid", "o:interface": "String", "o:interfaceState": "String", "o:stateTypeId": "Uuid", @@ -3098,7 +2590,6 @@ ], "Tag": { "appId": "String", - "d:o:deviceId": "Uuid", "o:ruleId": "Uuid", "o:thingId": "Uuid", "o:value": "String", @@ -3146,7 +2637,6 @@ "$ref:ThingClass" ], "ThingDescriptor": { - "d:r:deviceParams": "$ref:ParamList", "r:description": "String", "r:id": "Uuid", "r:o:thingId": "Uuid", diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index db10112b..697b95dc 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,10 +1,7 @@ TEMPLATE = subdirs SUBDIRS = \ - actions \ configurations \ - devices \ - events \ integrations \ ioconnections \ jsonrpc \ @@ -16,7 +13,6 @@ SUBDIRS = \ pythonplugins \ rules \ scripts \ - states \ tags \ timemanager \ userloading \ diff --git a/tests/auto/devices/devices.pro b/tests/auto/devices/devices.pro deleted file mode 100644 index 1b9e2ef3..00000000 --- a/tests/auto/devices/devices.pro +++ /dev/null @@ -1,5 +0,0 @@ -include(../../../nymea.pri) -include(../autotests.pri) - -TARGET = testdevices -SOURCES += testdevices.cpp diff --git a/tests/auto/devices/testdevices.cpp b/tests/auto/devices/testdevices.cpp deleted file mode 100644 index eedcb0d1..00000000 --- a/tests/auto/devices/testdevices.cpp +++ /dev/null @@ -1,2185 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "nymeatestbase.h" -#include "nymeacore.h" -#include "nymeasettings.h" - -#include "integrations/thingdiscoveryinfo.h" -#include "integrations/thingsetupinfo.h" - -#include "servers/mocktcpserver.h" -#include "jsonrpc/devicehandler.h" - -using namespace nymeaserver; - -class TestDevices : public NymeaTestBase -{ - Q_OBJECT - -private: - DeviceId m_mockThingAsyncId; - - inline void verifyDeviceError(const QVariant &response, Device::DeviceError error = Device::DeviceErrorNoError) { - verifyError(response, "deviceError", enumValueName(error)); - } - -private slots: - - void initTestCase(); - - void getPlugins(); - - void getPluginConfig_data(); - void getPluginConfig(); - - void setPluginConfig_data(); - void setPluginConfig(); - - void getSupportedVendors(); - - void getSupportedDevices_data(); - void getSupportedDevices(); - - void verifyInterfaces(); - - void addConfiguredDevice_data(); - void addConfiguredDevice(); - - void deviceAddedRemovedNotifications(); - - void deviceChangedNotifications(); - - void getConfiguredDevices(); - - void getConfiguredDevice_data(); - void getConfiguredDevice(); - - void storedDevices(); - - void discoverDevices_data(); - void discoverDevices(); - - void addPushButtonDevices_data(); - void addPushButtonDevices(); - - void addDisplayPinDevices_data(); - void addDisplayPinDevices(); - - void parentChildDevices(); - - void getActionTypes_data(); - void getActionTypes(); - - void getEventTypes_data(); - void getEventTypes(); - - void getStateTypes_data(); - void getStateTypes(); - - void getStateType_data(); - void getStateType(); - - void getStateValue_data(); - void getStateValue(); - - void getStateValues_data(); - void getStateValues(); - - void editDevices_data(); - void editDevices(); - - void testDeviceSettings(); - - void reconfigureDevices_data(); - void reconfigureDevices(); - - void reconfigureByDiscovery_data(); - void reconfigureByDiscovery(); - - void reconfigureByDiscoveryAndPair(); - void reconfigureAutodevice(); - - void testBrowsing_data(); - void testBrowsing(); - - void testExecuteBrowserItem_data(); - void testExecuteBrowserItem(); - - void testExecuteBrowserItemAction_data(); - void testExecuteBrowserItemAction(); - - void executeAction_data(); - void executeAction(); - - void triggerEvent(); - void triggerStateChangeEvent(); - - void params(); - - void asyncSetupEmitsSetupStatusUpdate(); - - // Keep those at last as they will remove devices - void removeDevice_data(); - void removeDevice(); - - void removeAutoDevice(); - - void discoverDeviceParenting(); -}; - -void TestDevices::initTestCase() -{ - NymeaTestBase::initTestCase(); - QLoggingCategory::setFilterRules("*.debug=false\n" - "Tests.debug=true\n" - "Mock.debug=true\n" - ); - - // Adding an async mock device to be used in tests below - QVariantMap params; - params.insert("deviceClassId", mockThingClassId); - params.insert("name", "Mock Device (Async)"); - - QVariantList deviceParams; - - QVariantMap asyncParam; - asyncParam.insert("paramTypeId", mockThingAsyncParamTypeId); - asyncParam.insert("value", true); - deviceParams.append(asyncParam); - - QVariantMap httpParam; - httpParam.insert("paramTypeId", mockThingHttpportParamTypeId); - httpParam.insert("value", 8765); - deviceParams.append(httpParam); - - params.insert("deviceParams", deviceParams); - - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - - m_mockThingAsyncId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY2(!m_mockThingAsyncId.isNull(), "Creating an async mock device failed"); - - qCDebug(dcTests()) << "Created Async mock device with ID" << m_mockThingAsyncId; -} - -void TestDevices::getPlugins() -{ - QVariant response = injectAndWait("Devices.GetPlugins"); - - QVariantList plugins = response.toMap().value("params").toMap().value("plugins").toList(); - - QCOMPARE(plugins.count() > 0, true); - bool found = false; - foreach (const QVariant &listEntry, plugins) { - if (PluginId(listEntry.toMap().value("id").toString()) == mockPluginId) { - found = true; - } - } - QCOMPARE(found, true); -} - -void TestDevices::getPluginConfig_data() -{ - QTest::addColumn("pluginId"); - QTest::addColumn("error"); - - QTest::newRow("valid plugin") << mockPluginId << Device::DeviceErrorNoError; - QTest::newRow("invalid plugin") << PluginId::createPluginId() << Device::DeviceErrorPluginNotFound; -} - -void TestDevices::getPluginConfig() -{ - QFETCH(PluginId, pluginId); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("pluginId", pluginId); - QVariant response = injectAndWait("Devices.GetPluginConfiguration", params); - verifyDeviceError(response, error); -} - -void TestDevices::setPluginConfig_data() -{ - QTest::addColumn("pluginId"); - QTest::addColumn("value"); - QTest::addColumn("error"); - - QTest::newRow("valid") << mockPluginId << QVariant(13) << Device::DeviceErrorNoError; - QTest::newRow("invalid plugin") << PluginId::createPluginId() << QVariant(13) << Device::DeviceErrorPluginNotFound; - QTest::newRow("too big") << mockPluginId << QVariant(130) << Device::DeviceErrorInvalidParameter; - QTest::newRow("too small") << mockPluginId << QVariant(-13) << Device::DeviceErrorInvalidParameter; - QTest::newRow("wrong type") << mockPluginId << QVariant("wrontType") << Device::DeviceErrorInvalidParameter; -} - -void TestDevices::setPluginConfig() -{ - QFETCH(PluginId, pluginId); - QFETCH(QVariant, value); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("pluginId", pluginId); - - QVariantList configuration; - QVariantMap configParam; - configParam.insert("paramTypeId", mockPluginConfigParamIntParamTypeId); - configParam.insert("value", value); - configuration.append(configParam); - params.insert("configuration", configuration); - QVariant response = injectAndWait("Devices.SetPluginConfiguration", params); - verifyDeviceError(response, error); - - if (error == Device::DeviceErrorNoError) { - params.clear(); - params.insert("pluginId", pluginId); - response = injectAndWait("Devices.GetPluginConfiguration", params); - verifyDeviceError(response); - qDebug() << value << response.toMap().value("params").toMap().value("configuration").toList().first(); - QVERIFY2(ParamTypeId(response.toMap().value("params").toMap().value("configuration").toList().first().toMap().value("paramTypeId").toString()) == mockPluginConfigParamIntParamTypeId, "Value not set correctly"); - QVERIFY2(response.toMap().value("params").toMap().value("configuration").toList().first().toMap().value("value") == value, "Value not set correctly"); - } -} - -void TestDevices::getSupportedVendors() -{ - QVariant supportedVendors = injectAndWait("Devices.GetSupportedVendors"); - qDebug() << "response" << supportedVendors; - - // Make sure there is exactly 1 supported Vendor named "guh" - QVariantList vendorList = supportedVendors.toMap().value("params").toMap().value("vendors").toList(); - QCOMPARE(vendorList.count() > 0, true); - bool found = false; - foreach (const QVariant &listEntry, vendorList) { - if (VendorId(listEntry.toMap().value("id").toString()) == nymeaVendorId) { - found = true; - } - } - QCOMPARE(found, true); -} - -void TestDevices::getSupportedDevices_data() -{ - QTest::addColumn("vendorId"); - QTest::addColumn("resultCount"); - - QTest::newRow("vendor guh") << nymeaVendorId << 1; - QTest::newRow("no filter") << VendorId() << 1; - QTest::newRow("invalid vendor") << VendorId("93e7d361-8025-4354-b17e-b68406c800bc") << 0; -} - -void TestDevices::getSupportedDevices() -{ - QFETCH(VendorId, vendorId); - QFETCH(int, resultCount); - - QVariantMap params; - if (!vendorId.isNull()) { - params.insert("vendorId", vendorId); - } - QVariant result = injectAndWait("Devices.GetSupportedDevices", params); - - QVariantList supportedDevices = result.toMap().value("params").toMap().value("deviceClasses").toList(); - // Make sure there are the right amount of supported device classes with the name Mock Device - QCOMPARE(supportedDevices.count() >= resultCount, true); -} - -void TestDevices::verifyInterfaces() -{ - QVariantMap params; - params.insert("vendorId", nymeaVendorId); - QVariant result = injectAndWait("Devices.GetSupportedDevices", params); - QVariantList supportedDevices = result.toMap().value("params").toMap().value("deviceClasses").toList(); - - QVariantMap mockDevice; - foreach (const QVariant &deviceClass, supportedDevices) { - if (deviceClass.toMap().value("id").toUuid() == mockThingClassId) { - mockDevice = deviceClass.toMap(); - } - } - QVERIFY(!mockDevice.isEmpty()); - - QVariantList interfaces = mockDevice.value("interfaces").toList(); - QVariantList expectedInterfaces = {"system", "light", "power", "battery", "wirelessconnectable", "connectable", "update"}; - qCDebug(dcTests()) << interfaces; - qCDebug(dcTests()) << expectedInterfaces; - QCOMPARE(interfaces, expectedInterfaces); -} - -void TestDevices::addConfiguredDevice_data() -{ - QTest::addColumn("thingClassId"); - QTest::addColumn("deviceParams"); - QTest::addColumn("jsonValidation"); - QTest::addColumn("deviceError"); - - QVariantMap httpportParam; - httpportParam.insert("paramTypeId", mockThingHttpportParamTypeId.toString()); - httpportParam.insert("value", m_mockThing1Port - 1); - QVariantMap asyncParam; - asyncParam.insert("paramTypeId", mockThingAsyncParamTypeId); - asyncParam.insert("value", true); - QVariantMap brokenParam; - brokenParam.insert("paramTypeId", mockThingBrokenParamTypeId); - brokenParam.insert("value", true); - - QVariantList deviceParams; - - deviceParams.clear(); deviceParams << httpportParam; - QTest::newRow("User, JustAdd") << mockThingClassId << deviceParams << true << Device::DeviceErrorNoError; - deviceParams.clear(); deviceParams << httpportParam << asyncParam; - QTest::newRow("User, JustAdd, Async") << mockThingClassId << deviceParams << true << Device::DeviceErrorNoError; - QTest::newRow("Invalid ThingClassId") << ThingClassId::createThingClassId() << deviceParams << true << Device::DeviceErrorDeviceClassNotFound; - deviceParams.clear(); deviceParams << httpportParam << brokenParam; - QTest::newRow("Setup failure") << mockThingClassId << deviceParams << true << Device::DeviceErrorSetupFailed; - deviceParams.clear(); deviceParams << httpportParam << asyncParam << brokenParam; - QTest::newRow("Setup failure, Async") << mockThingClassId << deviceParams << true << Device::DeviceErrorSetupFailed; - - QVariantList invalidDeviceParams; - QTest::newRow("User, JustAdd, missing params") << mockThingClassId << invalidDeviceParams << true << Device::DeviceErrorMissingParameter; - - QVariantMap fakeparam; - fakeparam.insert("paramTypeId", ParamTypeId::createParamTypeId()); - invalidDeviceParams.append(fakeparam); - QTest::newRow("User, JustAdd, invalid param") << mockThingClassId << invalidDeviceParams << false << Device::DeviceErrorMissingParameter; - - QVariantMap fakeparam2; - fakeparam2.insert("paramTypeId", mockThingHttpportParamTypeId.toString()); - fakeparam2.insert("value", "blabla"); - invalidDeviceParams.clear(); - invalidDeviceParams.append(fakeparam2); - QTest::newRow("User, JustAdd, wrong param") << mockThingClassId << invalidDeviceParams << true << Device::DeviceErrorInvalidParameter; - - deviceParams.clear(); deviceParams << httpportParam << fakeparam; - QTest::newRow("User, JustAdd, additional invalid param") << mockThingClassId << deviceParams << false << Device::DeviceErrorInvalidParameter; - - deviceParams.clear(); deviceParams << httpportParam << fakeparam2; - QTest::newRow("User, JustAdd, duplicate param") << mockThingClassId << deviceParams << true << Device::DeviceErrorInvalidParameter; - -} - -void TestDevices::addConfiguredDevice() -{ - QFETCH(ThingClassId, thingClassId); - QFETCH(QVariantList, deviceParams); - QFETCH(bool, jsonValidation); - QFETCH(Device::DeviceError, deviceError); - - QVariantMap params; - params.insert("deviceClassId", thingClassId); - params.insert("name", "Test Add Device"); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - - if (!jsonValidation) { - QCOMPARE(response.toMap().value("status").toString(), QString("error")); - return; - } - verifyDeviceError(response, deviceError); - - if (deviceError == Device::DeviceErrorNoError) { - QUuid deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - params.clear(); - params.insert("deviceId", deviceId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); - } -} - -void TestDevices::deviceAddedRemovedNotifications() -{ - enableNotifications({"Devices"}); - - // Setup connection to mock client - QSignalSpy clientSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - // add device and wait for notification - QVariantList deviceParams; - QVariantMap httpportParam; - httpportParam.insert("paramTypeId", mockThingHttpportParamTypeId); - httpportParam.insert("value", 5678); - deviceParams.append(httpportParam); - - QVariantMap params; clientSpy.clear(); - params.insert("deviceClassId", mockThingClassId); - params.insert("name", "Mock device"); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - if (clientSpy.count() == 0) clientSpy.wait(); - verifyDeviceError(response); - QVariantMap notificationDeviceMap = checkNotification(clientSpy, "Devices.DeviceAdded").toMap().value("params").toMap().value("device").toMap(); - - ThingId deviceId = ThingId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!deviceId.isNull()); - - // check the DeviceAdded notification - QCOMPARE(notificationDeviceMap.value("deviceClassId").toUuid(), QUuid(mockThingClassId)); - QCOMPARE(notificationDeviceMap.value("id").toUuid(), QUuid(deviceId)); - foreach (const QVariant ¶m, notificationDeviceMap.value("params").toList()) { - if (param.toMap().value("name").toString() == "httpport") { - QCOMPARE(param.toMap().value("value").toInt(), httpportParam.value("value").toInt()); - } - } - - // now remove the device and check the device removed notification - params.clear(); response.clear(); clientSpy.clear(); - params.insert("deviceId", deviceId); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - if (clientSpy.count() == 0) clientSpy.wait(); - verifyDeviceError(response); - checkNotification(clientSpy, "Devices.DeviceRemoved"); - - QCOMPARE(disableNotifications(), true); -} - -void TestDevices::deviceChangedNotifications() -{ - enableNotifications({"Devices"}); - - // Setup connection to mock client - QSignalSpy clientSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - // ADD - // add device and wait for notification - QVariantList deviceParams; - QVariantMap httpportParam; - httpportParam.insert("paramTypeId", mockThingHttpportParamTypeId); - httpportParam.insert("value", 23234); - deviceParams.append(httpportParam); - - clientSpy.clear(); - QVariantMap params; - params.insert("deviceClassId", mockThingClassId); - params.insert("name", "Mock"); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - ThingId deviceId = ThingId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!deviceId.isNull()); - if (clientSpy.count() == 0) clientSpy.wait(); - verifyDeviceError(response); - QVariantMap notificationDeviceMap = checkNotification(clientSpy, "Devices.DeviceAdded").toMap().value("params").toMap().value("device").toMap(); - - QCOMPARE(notificationDeviceMap.value("deviceClassId").toUuid(), QUuid(mockThingClassId)); - QCOMPARE(notificationDeviceMap.value("id").toUuid(), QUuid(deviceId)); - foreach (const QVariant ¶m, notificationDeviceMap.value("params").toList()) { - if (param.toMap().value("name").toString() == "httpport") { - QCOMPARE(param.toMap().value("value").toInt(), httpportParam.value("value").toInt()); - } - } - - // RECONFIGURE - // now reconfigure the device and check the deviceChanged notification - QVariantList newDeviceParams; - QVariantMap newHttpportParam; - newHttpportParam.insert("paramTypeId", mockThingHttpportParamTypeId); - newHttpportParam.insert("value", 45473); - newDeviceParams.append(newHttpportParam); - - params.clear(); response.clear(); clientSpy.clear(); - params.insert("deviceId", deviceId); - params.insert("deviceParams", newDeviceParams); - response = injectAndWait("Devices.ReconfigureDevice", params); - if (clientSpy.count() == 0) clientSpy.wait(); - verifyDeviceError(response); - QVariantMap reconfigureDeviceNotificationMap = checkNotification(clientSpy, "Devices.DeviceChanged").toMap().value("params").toMap().value("device").toMap(); - QCOMPARE(reconfigureDeviceNotificationMap.value("deviceClassId").toUuid(), QUuid(mockThingClassId)); - QCOMPARE(reconfigureDeviceNotificationMap.value("id").toUuid(), QUuid(deviceId)); - foreach (const QVariant ¶m, reconfigureDeviceNotificationMap.value("params").toList()) { - if (param.toMap().value("name").toString() == "httpport") { - QCOMPARE(param.toMap().value("value").toInt(), newHttpportParam.value("value").toInt()); - } - } - - // EDIT device name - QString deviceName = "Test device 1234"; - params.clear(); response.clear(); clientSpy.clear(); - params.insert("deviceId", deviceId); - params.insert("name", deviceName); - response = injectAndWait("Devices.EditDevice", params); - if (clientSpy.count() == 0) clientSpy.wait(); - verifyDeviceError(response); - QVariantMap editDeviceNotificationMap = checkNotification(clientSpy, "Devices.DeviceChanged").toMap().value("params").toMap().value("device").toMap(); - QCOMPARE(editDeviceNotificationMap.value("deviceClassId").toUuid(), QUuid(mockThingClassId)); - QCOMPARE(editDeviceNotificationMap.value("id").toUuid(), QUuid(deviceId)); - QCOMPARE(editDeviceNotificationMap.value("name").toString(), deviceName); - - // REMOVE - // now remove the device and check the device removed notification - params.clear(); response.clear(); clientSpy.clear(); - params.insert("deviceId", deviceId); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - if (clientSpy.count() == 0) clientSpy.wait(); - verifyDeviceError(response); - checkNotification(clientSpy, "Devices.DeviceRemoved"); - checkNotification(clientSpy, "Logging.LogDatabaseUpdated"); -} - -void TestDevices::getConfiguredDevices() -{ - QVariant response = injectAndWait("Devices.GetConfiguredDevices"); - - QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); - QCOMPARE(devices.count(), 3); // There should be: one auto created mock device, one created in NymeaTestBase::initTestcase() and one created in TestDevices::initTestCase() -} - -void TestDevices::getConfiguredDevice_data() -{ - QTest::addColumn("deviceId"); - QTest::addColumn("expectedError"); - - QTest::newRow("valid deviceId") << DeviceId(m_mockThingId) << Device::DeviceErrorNoError; - QTest::newRow("invalid deviceId") << DeviceId::createDeviceId() << Device::DeviceErrorDeviceNotFound; -} - -void TestDevices::getConfiguredDevice() -{ - QFETCH(DeviceId, deviceId); - QFETCH(Device::DeviceError, expectedError); - - QVariantMap params; - params.insert("deviceId", deviceId); - QVariant response = injectAndWait("Devices.GetConfiguredDevices", params); - -// qCDebug(dcTests()) << qUtf8Printable(QJsonDocument::fromVariant(response).toJson()); - - if (expectedError == Device::DeviceErrorNoError) { - QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); - QCOMPARE(devices.count(), 1); - } -} - -void TestDevices::storedDevices() -{ - QVariantMap params; - params.insert("deviceClassId", mockThingClassId); - params.insert("name", "Test stored Device"); - QVariantList deviceParams; - QVariantMap asyncParam; - asyncParam.insert("paramTypeId", mockThingAsyncParamTypeId); - asyncParam.insert("value", false); - deviceParams.append(asyncParam); - QVariantMap brokenParam; - brokenParam.insert("paramTypeId", mockThingBrokenParamTypeId); - brokenParam.insert("value", false); - deviceParams.append(brokenParam); - QVariantMap httpportParam; - httpportParam.insert("paramTypeId", mockThingHttpportParamTypeId); - httpportParam.insert("value", 8889); - deviceParams.append(httpportParam); - params.insert("deviceParams", deviceParams); - - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - verifyDeviceError(response); - DeviceId addedDeviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!addedDeviceId.isNull()); - - // Restart the core instance to check if settings are loaded at startup - restartServer(); - - response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); - - bool found = false; - foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { - if (DeviceId(device.toMap().value("id").toString()) == addedDeviceId) { - qDebug() << "found added device" << device.toMap().value("params"); - qDebug() << "expected deviceParams:" << deviceParams; - verifyParams(deviceParams, device.toMap().value("params").toList()); - found = true; - break; - } - } - QVERIFY2(found, "Device missing in config!"); - - params.clear(); - params.insert("deviceId", addedDeviceId); - qCDebug(dcTests()) << "Cleaning up mock device again"; - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); -} - -void TestDevices::discoverDevices_data() -{ - QTest::addColumn("thingClassId"); - QTest::addColumn("resultCount"); - QTest::addColumn("error"); - QTest::addColumn("discoveryParams"); - - QVariantList discoveryParams; - QVariantMap resultCountParam; - resultCountParam.insert("paramTypeId", mockDiscoveryResultCountParamTypeId); - resultCountParam.insert("value", 1); - discoveryParams.append(resultCountParam); - - QTest::newRow("valid ThingClassId") << mockThingClassId << 2 << Device::DeviceErrorNoError << QVariantList(); - QTest::newRow("valid ThingClassId with params") << mockThingClassId << 1 << Device::DeviceErrorNoError << discoveryParams; - QTest::newRow("invalid ThingClassId") << ThingClassId::createThingClassId() << 0 << Device::DeviceErrorDeviceClassNotFound << QVariantList(); -} - -void TestDevices::discoverDevices() -{ - QFETCH(ThingClassId, thingClassId); - QFETCH(int, resultCount); - QFETCH(Device::DeviceError, error); - QFETCH(QVariantList, discoveryParams); - - QVariantMap params; - params.insert("deviceClassId", thingClassId); - params.insert("discoveryParams", discoveryParams); - QVariant response = injectAndWait("Devices.GetDiscoveredDevices", params); - - verifyDeviceError(response, error); - if (error == Device::DeviceErrorNoError) { - QCOMPARE(response.toMap().value("params").toMap().value("deviceDescriptors").toList().count(), resultCount); - } - - // If we found something, lets try to add it - if (error == Device::DeviceErrorNoError) { - ThingDescriptorId descriptorId = ThingDescriptorId(response.toMap().value("params").toMap().value("deviceDescriptors").toList().first().toMap().value("id").toString()); - - params.clear(); - params.insert("deviceClassId", thingClassId); - params.insert("name", "Discoverd mock device"); - params.insert("deviceDescriptorId", descriptorId.toString()); - response = injectAndWait("Devices.AddConfiguredDevice", params); - - verifyDeviceError(response); - - DeviceId deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - params.clear(); - params.insert("deviceId", deviceId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); - } -} - -void TestDevices::addPushButtonDevices_data() -{ - QTest::addColumn("thingClassId"); - QTest::addColumn("error"); - QTest::addColumn("waitForButtonPressed"); - - QTest::newRow("Valid: Add PushButton device") << pushButtonMockThingClassId << Device::DeviceErrorNoError << true; - QTest::newRow("Invalid: Add PushButton device (press to early)") << pushButtonMockThingClassId << Device::DeviceErrorAuthenticationFailure << false; -} - -void TestDevices::addPushButtonDevices() -{ - QFETCH(ThingClassId, thingClassId); - QFETCH(Device::DeviceError, error); - QFETCH(bool, waitForButtonPressed); - - // Discover device - QVariantList discoveryParams; - QVariantMap resultCountParam; - resultCountParam.insert("paramTypeId", pushButtonMockDiscoveryResultCountParamTypeId); - resultCountParam.insert("value", 1); - discoveryParams.append(resultCountParam); - - QVariantMap params; - params.insert("deviceClassId", thingClassId); - params.insert("discoveryParams", discoveryParams); - QVariant response = injectAndWait("Devices.GetDiscoveredDevices", params); - - verifyDeviceError(response, Device::DeviceErrorNoError); - QCOMPARE(response.toMap().value("params").toMap().value("deviceDescriptors").toList().count(), 1); - - - // Pair device - ThingDescriptorId descriptorId = ThingDescriptorId(response.toMap().value("params").toMap().value("deviceDescriptors").toList().first().toMap().value("id").toString()); - params.clear(); - params.insert("deviceClassId", thingClassId); - params.insert("name", "Pushbutton device"); - params.insert("deviceDescriptorId", descriptorId.toString()); - response = injectAndWait("Devices.PairDevice", params); - - verifyDeviceError(response); - - PairingTransactionId pairingTransactionId(response.toMap().value("params").toMap().value("pairingTransactionId").toString()); - QString displayMessage = response.toMap().value("params").toMap().value("displayMessage").toString(); - - qDebug() << "displayMessage" << displayMessage; - - if (waitForButtonPressed) - QTest::qWait(3500); - - // Confirm pairing - params.clear(); - params.insert("pairingTransactionId", pairingTransactionId.toString()); - response = injectAndWait("Devices.ConfirmPairing", params); - - verifyDeviceError(response, error); - - if (error == Device::DeviceErrorNoError) { - DeviceId deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - params.clear(); - params.insert("deviceId", deviceId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); - } -} - -void TestDevices::addDisplayPinDevices_data() -{ - QTest::addColumn("thingClassId"); - QTest::addColumn("error"); - QTest::addColumn("secret"); - - QTest::newRow("Valid: Add DisplayPin device") << displayPinMockThingClassId << Device::DeviceErrorNoError << "243681"; - QTest::newRow("Invalid: Add DisplayPin device (wrong pin)") << displayPinMockThingClassId << Device::DeviceErrorAuthenticationFailure << "243682"; -} - -void TestDevices::addDisplayPinDevices() -{ - QFETCH(ThingClassId, thingClassId); - QFETCH(Device::DeviceError, error); - QFETCH(QString, secret); - - // Discover device - QVariantList discoveryParams; - QVariantMap resultCountParam; - resultCountParam.insert("paramTypeId", displayPinMockDiscoveryResultCountParamTypeId); - resultCountParam.insert("value", 1); - discoveryParams.append(resultCountParam); - - QVariantMap params; - params.insert("deviceClassId", thingClassId); - params.insert("discoveryParams", discoveryParams); - QVariant response = injectAndWait("Devices.GetDiscoveredDevices", params); - - verifyDeviceError(response, Device::DeviceErrorNoError); - QCOMPARE(response.toMap().value("params").toMap().value("deviceDescriptors").toList().count(), 1); - - // Pair device - ThingDescriptorId descriptorId = ThingDescriptorId(response.toMap().value("params").toMap().value("deviceDescriptors").toList().first().toMap().value("id").toString()); - params.clear(); - params.insert("deviceClassId", thingClassId); - params.insert("name", "Display pin mock device"); - params.insert("deviceDescriptorId", descriptorId.toString()); - response = injectAndWait("Devices.PairDevice", params); - - verifyDeviceError(response); - - PairingTransactionId pairingTransactionId(response.toMap().value("params").toMap().value("pairingTransactionId").toString()); - QString displayMessage = response.toMap().value("params").toMap().value("displayMessage").toString(); - - qDebug() << "displayMessage" << displayMessage; - - params.clear(); - params.insert("pairingTransactionId", pairingTransactionId.toString()); - params.insert("secret", secret); - response = injectAndWait("Devices.ConfirmPairing", params); - - verifyDeviceError(response, error); - - if (error == Device::DeviceErrorNoError) { - DeviceId deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - params.clear(); - params.insert("deviceId", deviceId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); - } - - -} - -void TestDevices::parentChildDevices() -{ - // add parent device - QVariantMap params; - params.insert("deviceClassId", parentMockThingClassId); - params.insert("name", "Parent device"); - - QSignalSpy deviceAddedSpy(NymeaCore::instance()->thingManager(), &ThingManager::thingAdded); - - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - verifyDeviceError(response); - - DeviceId parentId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!parentId.isNull()); - - deviceAddedSpy.wait(); - QCOMPARE(deviceAddedSpy.count(), 2); - - // find child device - response = injectAndWait("Devices.GetConfiguredDevices"); - - QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); - - DeviceId childDeviceId; - foreach (const QVariant deviceVariant, devices) { - QVariantMap deviceMap = deviceVariant.toMap(); - - if (deviceMap.value("deviceClassId").toUuid() == childMockThingClassId) { - if (deviceMap.value("parentId").toUuid() == parentId) { - childDeviceId = DeviceId(deviceMap.value("id").toString()); - break; - } - } - } - QVERIFY2(!childDeviceId.isNull(), QString("Could not find child device:\nParent ID:%1\nResponse:%2") - .arg(parentId.toString()) - .arg(qUtf8Printable(QJsonDocument::fromVariant(response).toJson())) - .toUtf8()); - - // Try to remove the child device - params.clear(); - params.insert("deviceId", childDeviceId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response, Device::DeviceErrorDeviceIsChild); - - // check if the child device is still there - response = injectAndWait("Devices.GetConfiguredDevices"); - devices = response.toMap().value("params").toMap().value("devices").toList(); - bool found = false; - foreach (const QVariant deviceVariant, devices) { - QVariantMap deviceMap = deviceVariant.toMap(); - if (deviceMap.value("deviceClassId").toUuid() == childMockThingClassId) { - if (deviceMap.value("id").toUuid() == childDeviceId) { - found = true; - break; - } - } - } - QVERIFY2(found, "Could not find child device."); - - // remove the parent device - params.clear(); - params.insert("deviceId", parentId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); - - // check if the child device is still there - response = injectAndWait("Devices.GetConfiguredDevices"); - devices = response.toMap().value("params").toMap().value("devices").toList(); - found = false; - foreach (const QVariant deviceVariant, devices) { - QVariantMap deviceMap = deviceVariant.toMap(); - if (deviceMap.value("deviceClassId").toString() == childMockThingClassId.toString()) { - if (deviceMap.value("id") == childDeviceId.toString()) { - found = true; - break; - } - } - } - QVERIFY2(!found, "Could not find child device."); -} - -void TestDevices::getActionTypes_data() -{ - QTest::addColumn("thingClassId"); - QTest::addColumn >("actionTypeTestData"); - - QTest::newRow("valid deviceclass") << mockThingClassId - << (QList() << mockIntWithLimitsActionTypeId << mockAsyncActionTypeId << mockAsyncFailingActionTypeId << mockFailingActionTypeId << mockWithoutParamsActionTypeId << mockPowerActionTypeId << mockWithoutParamsActionTypeId << mockBatteryLevelActionTypeId << mockSignalStrengthActionTypeId << mockUpdateStatusActionTypeId << mockPerformUpdateActionTypeId); - QTest::newRow("invalid deviceclass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << QList(); -} - -void TestDevices::getActionTypes() -{ - QFETCH(ThingClassId, thingClassId); - QFETCH(QList, actionTypeTestData); - - QVariantMap params; - params.insert("deviceClassId", thingClassId); - QVariant response = injectAndWait("Devices.GetActionTypes", params); - - QVariantList actionTypes = response.toMap().value("params").toMap().value("actionTypes").toList(); - QCOMPARE(actionTypes.count(), actionTypeTestData.count()); - foreach (const ActionTypeId &testDataId, actionTypeTestData) { - bool found = false; - foreach (const QVariant &at, actionTypes) { - if (testDataId == at.toMap().value("id").toUuid()) { - found = true; - break; - } - } - QVERIFY(found); - } -} - -void TestDevices::getEventTypes_data() -{ - QTest::addColumn("deviceClassId"); - QTest::addColumn("resultCount"); - - QTest::newRow("valid deviceclass") << mockThingClassId << 14; - QTest::newRow("invalid deviceclass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << 0; -} - -void TestDevices::getEventTypes() -{ - QFETCH(ThingClassId, deviceClassId); - QFETCH(int, resultCount); - - QVariantMap params; - params.insert("deviceClassId", deviceClassId); - QVariant response = injectAndWait("Devices.GetEventTypes", params); - - qDebug() << response; - - QVariantList eventTypes = response.toMap().value("params").toMap().value("eventTypes").toList(); - QCOMPARE(eventTypes.count(), resultCount); - -} - -void TestDevices::getStateTypes_data() -{ - QTest::addColumn("thingClassId"); - QTest::addColumn("resultCount"); - - QTest::newRow("valid deviceclass") << mockThingClassId << 12; - QTest::newRow("invalid deviceclass") << ThingClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << 0; -} - -void TestDevices::getStateTypes() -{ - QFETCH(ThingClassId, thingClassId); - QFETCH(int, resultCount); - - QVariantMap params; - params.insert("deviceClassId", thingClassId); - QVariant response = injectAndWait("Devices.GetStateTypes", params); - - QVariantList stateTypes = response.toMap().value("params").toMap().value("stateTypes").toList(); - QCOMPARE(stateTypes.count(), resultCount); - if (resultCount > 0) { - QCOMPARE(stateTypes.first().toMap().value("id").toUuid().toString(), mockIntStateTypeId.toString()); - } -} - -void TestDevices::getStateType_data() -{ - QTest::addColumn("stateTypeId"); - QTest::addColumn("error"); - - QTest::newRow("valid int state") << mockIntStateTypeId << Device::DeviceErrorNoError; - QTest::newRow("valid bool state") << mockBoolStateTypeId << Device::DeviceErrorNoError; - QTest::newRow("invalid stateTypeId") << StateTypeId::createStateTypeId() << Device::DeviceErrorStateTypeNotFound; -} - -void TestDevices::getStateType() -{ - QFETCH(StateTypeId, stateTypeId); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("stateTypeId", stateTypeId); - QVariant response = injectAndWait("States.GetStateType", params); - verifyDeviceError(response, error); - - if (error != Device::DeviceErrorNoError) - return; - - QVariantMap stateType = response.toMap().value("params").toMap().value("stateType").toMap(); - - QVERIFY2(!stateType.isEmpty(), "Got no stateType"); - QCOMPARE(stateType.value("id").toUuid().toString(), stateTypeId.toString()); -} - -void TestDevices::getStateValue_data() -{ - QTest::addColumn("deviceId"); - QTest::addColumn("stateTypeId"); - QTest::addColumn("statusCode"); - - QTest::newRow("valid deviceId") << DeviceId(m_mockThingId) << mockIntStateTypeId << Device::DeviceErrorNoError; - QTest::newRow("invalid deviceId") << DeviceId("094f8024-5caa-48c1-ab6a-de486a92088f") << mockIntStateTypeId << Device::DeviceErrorDeviceNotFound; - QTest::newRow("invalid statetypeId") << DeviceId(m_mockThingId) << StateTypeId("120514f1-343e-4621-9bff-dac616169df9") << Device::DeviceErrorStateTypeNotFound; -} - -void TestDevices::getStateValue() -{ - QFETCH(DeviceId, deviceId); - QFETCH(StateTypeId, stateTypeId); - QFETCH(Device::DeviceError, statusCode); - - QVariantMap params; - params.insert("deviceId", deviceId); - params.insert("stateTypeId", stateTypeId); - QVariant response = injectAndWait("Devices.GetStateValue", params); - - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), enumValueName(statusCode)); - if (statusCode == Device::DeviceErrorNoError) { - QVariant value = response.toMap().value("params").toMap().value("value"); - QCOMPARE(value.toInt(), 10); // Mock device has value 10 by default... - } -} - -void TestDevices::getStateValues_data() -{ - QTest::addColumn("deviceId"); - QTest::addColumn("statusCode"); - - QTest::newRow("valid deviceId") << DeviceId(m_mockThingId) << Device::DeviceErrorNoError; - QTest::newRow("invalid deviceId") << DeviceId("094f8024-5caa-48c1-ab6a-de486a92088f") << Device::DeviceErrorDeviceNotFound; -} - -void TestDevices::getStateValues() -{ - QFETCH(DeviceId, deviceId); - QFETCH(Device::DeviceError, statusCode); - - QVariantMap params; - params.insert("deviceId", deviceId); - QVariant response = injectAndWait("Devices.GetStateValues", params); - - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), enumValueName(statusCode)); - if (statusCode == Device::DeviceErrorNoError) { - QVariantList values = response.toMap().value("params").toMap().value("values").toList(); - QCOMPARE(values.count(), 12); // Mock device has 12 states... - } -} - -void TestDevices::editDevices_data() -{ - QTest::addColumn("name"); - - QTest::newRow("change name") << "New device name"; - QTest::newRow("change name") << "Foo device"; - QTest::newRow("change name") << "Bar device"; -} - -void TestDevices::editDevices() -{ - QFETCH(QString, name); - - QString originalName = "Test device"; - - // add device - QVariantList deviceParams; - QVariantMap httpportParam; - httpportParam.insert("paramTypeId", mockThingHttpportParamTypeId); - httpportParam.insert("value", 8889); - deviceParams.append(httpportParam); - - QVariantMap params; - params.insert("deviceClassId", mockThingClassId); - params.insert("name", originalName); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - verifyDeviceError(response); - DeviceId deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - - // edit device - params.clear(); - params.insert("deviceId", deviceId); - params.insert("name", name); - - response = injectAndWait("Devices.EditDevice", params); - verifyDeviceError(response); - - // verify changed - QString newName; - response = injectAndWait("Devices.GetConfiguredDevices"); - QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); - - foreach (const QVariant &deviceVariant, devices) { - QVariantMap device = deviceVariant.toMap(); - if (DeviceId(device.value("id").toString()) == deviceId) { - newName = device.value("name").toString(); - } - } - QCOMPARE(newName, name); - - restartServer(); - - // check if the changed name is still there after loading - response = injectAndWait("Devices.GetConfiguredDevices"); - devices = response.toMap().value("params").toMap().value("devices").toList(); - foreach (const QVariant &deviceVariant, devices) { - QVariantMap device = deviceVariant.toMap(); - if (DeviceId(device.value("id").toString()) == deviceId) { - newName = device.value("name").toString(); - break; - } - } - QCOMPARE(newName, name); - - params.clear(); - params.insert("deviceId", deviceId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); -} - -void TestDevices::testDeviceSettings() -{ - // add device - QVariantList deviceParams; - QVariantMap httpportParam; - httpportParam.insert("paramTypeId", mockThingHttpportParamTypeId); - httpportParam.insert("value", 8889); - deviceParams.append(httpportParam); - - QVariantMap params; - params.insert("deviceClassId", mockThingClassId); - params.insert("name", "Mock"); - params.insert("deviceParams", deviceParams); - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - verifyDeviceError(response); - DeviceId deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - - // check if default settings are loaded - params.clear(); - params.insert("deviceId", deviceId); - response = injectAndWait("Devices.GetConfiguredDevices", params); - QVariantList devices = response.toMap().value("params").toMap().value("devices").toList(); - QVERIFY2(devices.count() == 1, "Error creating device"); - - QVariantMap device = devices.first().toMap(); - QVERIFY2(DeviceId(device.value("id").toString()) == deviceId, "DeviceId not matching"); - - QVariantList settings = device.value("settings").toList(); - QCOMPARE(settings.count(), 3); - - QCOMPARE(settings.first().toMap().value("paramTypeId").toUuid(), QUuid(mockSettingsSetting1ParamTypeId)); - QVERIFY2(settings.first().toMap().value("value").toInt() == 5, "Setting 1 default value not matching"); - - // change a setting - params.clear(); - params.insert("deviceId", deviceId); - settings.clear(); - QVariantMap setting; - setting.insert("paramTypeId", mockSettingsSetting1ParamTypeId); - setting.insert("value", 7); - settings.append(setting); - params.insert("settings", settings); - response = injectAndWait("Devices.SetDeviceSettings", params); - - // Check if the change happened - params.clear(); - params.insert("deviceId", deviceId); - response = injectAndWait("Devices.GetConfiguredDevices", params); - devices = response.toMap().value("params").toMap().value("devices").toList(); - QVERIFY2(devices.count() == 1, "Error creating device"); - - device = devices.first().toMap(); - QVERIFY2(DeviceId(device.value("id").toString()) == deviceId, "DeviceId not matching"); - - settings = device.value("settings").toList(); - QCOMPARE(settings.count(), 3); - - QCOMPARE(settings.first().toMap().value("paramTypeId").toUuid(), QUuid(mockSettingsSetting1ParamTypeId)); - QVERIFY2(settings.first().toMap().value("value").toInt() == 7, "Setting 1 changed value not matching"); - - restartServer(); - - // Check if the change persisted - params.clear(); - params.insert("deviceId", deviceId); - response = injectAndWait("Devices.GetConfiguredDevices", params); - devices = response.toMap().value("params").toMap().value("devices").toList(); - QVERIFY2(devices.count() == 1, "Error creating device"); - - device = devices.first().toMap(); - QVERIFY2(DeviceId(device.value("id").toString()) == deviceId, "DeviceId not matching"); - - settings = device.value("settings").toList(); - QCOMPARE(settings.count(), 3); - - QCOMPARE(settings.first().toMap().value("paramTypeId").toUuid(), QUuid(mockSettingsSetting1ParamTypeId)); - QVERIFY2(settings.first().toMap().value("value").toInt() == 7, "Setting 1 changed value not persisting restart"); - -} - -void TestDevices::reconfigureDevices_data() -{ - QVariantList asyncChangeDeviceParams; - QVariantMap asyncParamDifferent; - asyncParamDifferent.insert("paramTypeId", mockThingAsyncParamTypeId); - asyncParamDifferent.insert("value", true); - asyncChangeDeviceParams.append(asyncParamDifferent); - - QVariantList httpportChangeDeviceParams; - QVariantMap httpportParamDifferent; - httpportParamDifferent.insert("paramTypeId", mockThingHttpportParamTypeId); - httpportParamDifferent.insert("value", 8893); // if change -> change also newPort in reconfigureDevices() - httpportChangeDeviceParams.append(httpportParamDifferent); - - QVariantList brokenChangedDeviceParams; - QVariantMap brokenParamDifferent; - brokenParamDifferent.insert("paramTypeId", mockThingBrokenParamTypeId); - brokenParamDifferent.insert("value", true); - brokenChangedDeviceParams.append(brokenParamDifferent); - - QVariantList asyncAndPortChangeDeviceParams; - asyncAndPortChangeDeviceParams.append(asyncParamDifferent); - asyncAndPortChangeDeviceParams.append(httpportParamDifferent); - - - QVariantList changeAllWritableDeviceParams; - changeAllWritableDeviceParams.append(asyncParamDifferent); - changeAllWritableDeviceParams.append(httpportParamDifferent); - - QTest::addColumn("broken"); - QTest::addColumn("newDeviceParams"); - QTest::addColumn("deviceError"); - - QTest::newRow("valid - change async param") << false << asyncChangeDeviceParams << Device::DeviceErrorParameterNotWritable; - QTest::newRow("valid - change httpport param") << false << httpportChangeDeviceParams << Device::DeviceErrorNoError; - QTest::newRow("invalid - change httpport and async param") << false << asyncAndPortChangeDeviceParams << Device::DeviceErrorParameterNotWritable; - QTest::newRow("invalid - change all params (except broken)") << false << changeAllWritableDeviceParams << Device::DeviceErrorParameterNotWritable; -} - -void TestDevices::reconfigureDevices() -{ - QFETCH(bool, broken); - QFETCH(QVariantList, newDeviceParams); - QFETCH(Device::DeviceError, deviceError); - - // add device - QVariantMap params; - params.insert("deviceClassId", mockThingClassId); - params.insert("name", "Device to edit"); - QVariantList deviceParams; - QVariantMap asyncParam; - asyncParam.insert("paramTypeId", mockThingAsyncParamTypeId); - asyncParam.insert("value", false); - deviceParams.append(asyncParam); - QVariantMap brokenParam; - brokenParam.insert("paramTypeId", mockThingBrokenParamTypeId); - brokenParam.insert("value", broken); - deviceParams.append(brokenParam); - QVariantMap httpportParam; - httpportParam.insert("paramTypeId", mockThingHttpportParamTypeId); - httpportParam.insert("value", 8892); - deviceParams.append(httpportParam); - params.insert("deviceParams", deviceParams); - - // add a mockdevice - QVariant response = injectAndWait("Devices.AddConfiguredDevice", params); - verifyDeviceError(response); - - DeviceId deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!deviceId.isNull()); - - // now EDIT the added device - response.clear(); - QVariantMap editParams; - editParams.insert("deviceId", deviceId); - editParams.insert("deviceParams", newDeviceParams); - response = injectAndWait("Devices.ReconfigureDevice", editParams); - verifyDeviceError(response, deviceError); - - // if the edit should have been successful - if (deviceError == Device::DeviceErrorNoError) { - response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); - - bool found = false; - foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { - if (DeviceId(device.toMap().value("id").toString()) == deviceId) { - qDebug() << "found added device" << device.toMap().value("params"); - qDebug() << "expected deviceParams:" << newDeviceParams; - // check if the edit was ok - verifyParams(newDeviceParams, device.toMap().value("params").toList(), false); - found = true; - break; - } - } - QVERIFY2(found, "Device missing in config!"); - - // Restart the core instance to check if settings are loaded at startup - restartServer(); - - response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); - - found = false; - foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { - if (DeviceId(device.toMap().value("id").toString()) == deviceId) { - qDebug() << "found added device" << device.toMap().value("params"); - qDebug() << "expected deviceParams:" << newDeviceParams; - // check if the edit was ok - verifyParams(newDeviceParams, device.toMap().value("params").toList(), false); - found = true; - break; - } - } - QVERIFY2(found, "Device missing in config!"); - - // delete it - params.clear(); - params.insert("deviceId", deviceId); - response.clear(); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); - return; - } else { - // The edit was not ok, check if the old params are still there - response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); - - bool found = false; - foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { - if (DeviceId(device.toMap().value("id").toString()) == deviceId) { - qDebug() << "found added device" << device.toMap().value("params"); - qDebug() << "expected deviceParams:" << newDeviceParams; - // check if the params are unchanged - verifyParams(deviceParams, device.toMap().value("params").toList()); - found = true; - break; - } - } - QVERIFY2(found, "Device missing in config!"); - - // Restart the core instance to check if settings are loaded at startup - restartServer(); - - response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); - - found = false; - foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { - if (DeviceId(device.toMap().value("id").toString()) == deviceId) { - qDebug() << "found added device" << device.toMap().value("params"); - qDebug() << "expected deviceParams:" << newDeviceParams; - // check if after the reboot the settings are unchanged - verifyParams(deviceParams, device.toMap().value("params").toList()); - found = true; - break; - } - } - QVERIFY2(found, "Device missing in config!"); - } - - // delete it - params.clear(); - params.insert("deviceId", deviceId); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); -} - - -void TestDevices::reconfigureByDiscovery_data() -{ - QTest::addColumn("thingClassId"); - QTest::addColumn("resultCount"); - QTest::addColumn("error"); - QTest::addColumn("discoveryParams"); - - QVariantList discoveryParams; - QVariantMap resultCountParam; - resultCountParam.insert("paramTypeId", mockDiscoveryResultCountParamTypeId); - resultCountParam.insert("value", 2); - discoveryParams.append(resultCountParam); - - QTest::newRow("discover 2 devices with params") << mockThingClassId << 2 << Device::DeviceErrorNoError << discoveryParams; -} - -void TestDevices::reconfigureByDiscovery() -{ - QFETCH(ThingClassId, thingClassId); - QFETCH(int, resultCount); - QFETCH(Device::DeviceError, error); - QFETCH(QVariantList, discoveryParams); - - qCDebug(dcTests()) << "Discovering..."; - QVariantMap params; - params.insert("deviceClassId", thingClassId); - params.insert("discoveryParams", discoveryParams); - QVariant response = injectAndWait("Devices.GetDiscoveredDevices", params); - - verifyDeviceError(response); - if (error == Device::DeviceErrorNoError) { - QCOMPARE(response.toMap().value("params").toMap().value("deviceDescriptors").toList().count(), resultCount); - } - - // add Discovered Device 1 port 55555 - QVariantList deviceDescriptors = response.toMap().value("params").toMap().value("deviceDescriptors").toList(); - - ThingDescriptorId descriptorId; - foreach (const QVariant &descriptor, deviceDescriptors) { - // find the device with port 55555 - if (descriptor.toMap().value("description").toString() == "55555") { - descriptorId = ThingDescriptorId(descriptor.toMap().value("id").toString()); - qDebug() << descriptorId.toString(); - break; - } - } - - QVERIFY(!descriptorId.isNull()); - - qCDebug(dcTests()) << "Adding..."; - - params.clear(); - response.clear(); - params.insert("deviceClassId", thingClassId); - params.insert("name", "Discoverd mock device"); - params.insert("deviceDescriptorId", descriptorId); - response = injectAndWait("Devices.AddConfiguredDevice", params); - - DeviceId deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!deviceId.isNull()); - - // and now rediscover and find the existing device in the discovery results - qCDebug(dcTests()) << "Re-Discovering..."; - - params.clear(); - response.clear(); - params.insert("deviceClassId", thingClassId); - params.insert("discoveryParams", discoveryParams); - response = injectAndWait("Devices.GetDiscoveredDevices", params); - - verifyDeviceError(response, error); - if (error == Device::DeviceErrorNoError) { - QCOMPARE(response.toMap().value("params").toMap().value("deviceDescriptors").toList().count(), resultCount); - } - - deviceDescriptors = response.toMap().value("params").toMap().value("deviceDescriptors").toList(); - - // find the already added device - descriptorId = ThingDescriptorId(); // reset it first - foreach (const QVariant &descriptor, deviceDescriptors) { - if (descriptor.toMap().value("deviceId").toUuid().toString() == deviceId.toString()) { - descriptorId = ThingDescriptorId(descriptor.toMap().value("id").toString()); - break; - } - } - QVERIFY2(!descriptorId.isNull(), QString("Device %1 not found in discovery results: %2").arg(deviceId.toString()).arg(qUtf8Printable(QJsonDocument::fromVariant(response).toJson())).toUtf8()); - - qCDebug(dcTests()) << "Reconfiguring..."; - - response.clear(); - params.clear(); - params.insert("deviceDescriptorId", descriptorId); - // override port param - QVariantMap portParam; - portParam.insert("paramTypeId", mockThingHttpportParamTypeId); - portParam.insert("value", "55556"); - params.insert("deviceParams", QVariantList() << portParam); - response = injectAndWait("Devices.ReconfigureDevice", params); - verifyDeviceError(response, error); - - response.clear(); - response = injectAndWait("Devices.GetConfiguredDevices", QVariantMap()); - - QVariantMap deviceMap; - bool found = false; - foreach (const QVariant device, response.toMap().value("params").toMap().value("devices").toList()) { - if (DeviceId(device.toMap().value("id").toString()) == deviceId) { - qDebug() << "found added device" << device.toMap().value("params"); - found = true; - deviceMap = device.toMap(); - break; - } - } - - QVERIFY2(found, "Device missing in config!"); - QCOMPARE(deviceMap.value("id").toUuid(), QUuid(deviceId)); - if (deviceMap.contains("setupComplete")) - QVERIFY2(deviceMap.value("setupComplete").toBool(), "Setup not completed after edit"); - - // Note: this shows that by discovery a not editable param (name) can be changed! - foreach (QVariant param, deviceMap.value("params").toList()) { - if (param.toMap().value("paramTypeId") == mockThingHttpportParamTypeId) { - QCOMPARE(param.toMap().value("value").toInt(), 55556); - } - } - - // check if the daemons are running - QNetworkAccessManager nam; - QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); - - // check if old daemon is still running (should not) - QNetworkRequest request(QUrl(QString("http://localhost:%1").arg(55555))); - QNetworkReply *reply = nam.get(request); - spy.wait(); - QVERIFY2(reply->error(), "The old daemon is still running"); - reply->deleteLater(); - - // check if the daemon is really running on the new port - request = QNetworkRequest(QUrl(QString("http://localhost:%1").arg(55556))); - reply = nam.get(request); - spy.wait(); - QVERIFY2(reply->error() == QNetworkReply::NoError, "The new daemon is not running"); - reply->deleteLater(); - - params.clear(); - params.insert("deviceId", deviceId.toString()); - response = injectAndWait("Devices.RemoveConfiguredDevice", params); - verifyDeviceError(response); -} - -void TestDevices::reconfigureByDiscoveryAndPair() -{ - QVariantList discoveryParams; - QVariantMap resultCountParam; - resultCountParam.insert("paramTypeId", displayPinMockDiscoveryResultCountParamTypeId); - resultCountParam.insert("value", 1); - discoveryParams.append(resultCountParam); - - qCDebug(dcTests()) << "Discovering devices..."; - - QVariantMap params; - params.insert("deviceClassId", displayPinMockThingClassId); - params.insert("discoveryParams", discoveryParams); - QVariant response = injectAndWait("Devices.GetDiscoveredDevices", params); - - verifyDeviceError(response); - QVariantList deviceDescriptors = response.toMap().value("params").toMap().value("deviceDescriptors").toList(); - - qCDebug(dcTests()) << "Discovery result:" << qUtf8Printable(QJsonDocument::fromVariant(deviceDescriptors).toJson(QJsonDocument::Indented)); - QCOMPARE(response.toMap().value("params").toMap().value("deviceDescriptors").toList().count(), 1); - - // add Discovered Device 1 port 55555 - - QVariant descriptor = deviceDescriptors.first(); - ThingDescriptorId descriptorId = ThingDescriptorId(descriptor.toMap().value("id").toString()); - QVERIFY2(!descriptorId.isNull(), "DeviceDescriptorId is Null"); - - qCDebug(dcTests()) << "Pairing descriptorId:" << descriptorId; - - params.clear(); - response.clear(); - params.insert("deviceClassId", displayPinMockThingClassId); - params.insert("name", "Discoverd mock device"); - params.insert("deviceDescriptorId", descriptorId); - response = injectAndWait("Devices.PairDevice", params); - verifyDeviceError(response); - - PairingTransactionId pairingTransactionId = PairingTransactionId(response.toMap().value("params").toMap().value("pairingTransactionId").toString()); - qCDebug(dcTests()) << "PairDevice result:" << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - - qCDebug(dcTests()) << "Confirming pairing for transaction ID" << pairingTransactionId; - params.clear(); - response.clear(); - params.insert("pairingTransactionId", pairingTransactionId.toString()); - params.insert("secret", "243681"); - response = injectAndWait("Devices.ConfirmPairing", params); - verifyDeviceError(response); - - DeviceId deviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!deviceId.isNull()); - - qCDebug(dcTests()) << "Discovering again..."; - - // and now rediscover, and edit the first device with the second - params.clear(); - response.clear(); - params.insert("deviceClassId", displayPinMockThingClassId); - params.insert("discoveryParams", discoveryParams); - response = injectAndWait("Devices.GetDiscoveredDevices", params); - - deviceDescriptors = response.toMap().value("params").toMap().value("deviceDescriptors").toList(); - qCDebug(dcTests()) << "Discovery result:" << qUtf8Printable(QJsonDocument::fromVariant(deviceDescriptors).toJson(QJsonDocument::Indented)); - - verifyDeviceError(response, Device::DeviceErrorNoError); - QCOMPARE(deviceDescriptors.count(), 1); - - descriptor = deviceDescriptors.first(); - QVERIFY2(DeviceId(descriptor.toMap().value("deviceId").toString()) == deviceId, "DeviceID not set in descriptor"); - - // get the descriptor again - descriptorId = ThingDescriptorId(descriptor.toMap().value("id").toString()); - - QVERIFY(!descriptorId.isNull()); - - qDebug() << "Reconfiguring device by pairing again" << descriptorId; - - params.clear(); - response.clear(); - params.insert("deviceClassId", displayPinMockThingClassId); - params.insert("name", "Discoverd mock device"); - params.insert("deviceDescriptorId", descriptorId); - response = injectAndWait("Devices.PairDevice", params); - verifyDeviceError(response); - - pairingTransactionId = PairingTransactionId(response.toMap().value("params").toMap().value("pairingTransactionId").toString()); - qCDebug(dcTests()) << "PairDevice result:" << qUtf8Printable(QJsonDocument::fromVariant(response).toJson(QJsonDocument::Indented)); - - - qCDebug(dcTests()) << "Confirming pairing for transaction ID" << pairingTransactionId; - params.clear(); - response.clear(); - params.insert("pairingTransactionId", pairingTransactionId.toString()); - params.insert("secret", "243681"); - response = injectAndWait("Devices.ConfirmPairing", params); - verifyDeviceError(response); - - deviceId = DeviceId(response.toMap().value("params").toMap().value("deviceId").toString()); - QVERIFY(!deviceId.isNull()); - -} - -void TestDevices::reconfigureAutodevice() -{ - qCDebug(dcTests()) << "Reconfigure auto device"; - - // Get the autodevice - QList devices = NymeaCore::instance()->thingManager()->findConfiguredThings(autoMockThingClassId); - QVERIFY2(devices.count() > 0, "There needs to be at least one auto-created Mock Device for this test"); - - // Get current auto device infos - Thing *currentDevice = devices.first(); - DeviceId deviceId = currentDevice->id(); - int currentPort = currentDevice->paramValue(autoMockThingHttpportParamTypeId).toInt(); - - // Trigger reconfigure signal in mock device - QNetworkAccessManager *nam = new QNetworkAccessManager(this); - QSignalSpy spy(nam, &QNetworkAccessManager::finished); - QNetworkReply *reply = nam->get(QNetworkRequest(QUrl(QString("http://localhost:%1/reconfigureautodevice").arg(currentPort)))); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - - Thing *device = NymeaCore::instance()->thingManager()->findConfiguredThing(deviceId); - QVERIFY(device); - int newPort = device->paramValue(autoMockThingHttpportParamTypeId).toInt(); - // Note: reconfigure autodevice increases the http port by 1 - QCOMPARE(newPort, currentPort + 1); -} - - -void TestDevices::removeDevice_data() -{ - QTest::addColumn("deviceId"); - QTest::addColumn("deviceError"); - - QTest::newRow("Existing Device") << DeviceId(m_mockThingId) << Device::DeviceErrorNoError; - QTest::newRow("Not existing Device") << DeviceId::createDeviceId() << Device::DeviceErrorDeviceNotFound; -// QTest::newRow("Auto device") << m_mockDeviceAutoId << Device::DeviceErrorCreationMethodNotSupported; -} - -void TestDevices::removeDevice() -{ - QFETCH(DeviceId, deviceId); - QFETCH(Device::DeviceError, deviceError); - - NymeaSettings settings(NymeaSettings::SettingsRoleThings); - settings.beginGroup("ThingConfig"); - if (deviceError == Device::DeviceErrorNoError) { - settings.beginGroup(m_mockThingId.toString()); - // Make sure we have some config values for this device - QVERIFY(settings.allKeys().count() > 0); - } - - QVariantMap params; - params.insert("deviceId", deviceId); - - QVariant response = injectAndWait("Devices.RemoveConfiguredDevice", params); - - verifyDeviceError(response, deviceError); - - if (Device::DeviceErrorNoError) { - // Make sure the device is gone from settings too - QCOMPARE(settings.allKeys().count(), 0); - } -} - -void TestDevices::removeAutoDevice() -{ - // Setup connection to mock client - QNetworkAccessManager *nam = new QNetworkAccessManager(this); - QSignalSpy spy(nam, SIGNAL(finished(QNetworkReply*))); - - // First try to make a manually created device disappear. It must not go away - - QList devices = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId); - int oldCount = devices.count(); - QVERIFY2(oldCount > 0, "There needs to be at least one configured Mock Device for this test"); - Thing *device = devices.first(); - - // trigger disappear signal in mock device - int port = device->paramValue(autoMockThingHttpportParamTypeId).toInt(); - QNetworkRequest request(QUrl(QString("http://localhost:%1/disappear").arg(port))); - QNetworkReply *reply = nam->get(request); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - QVERIFY2(NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId).count() == oldCount, "Mock device has disappeared even though it shouldn't"); - - // Ok, now do the same with an autocreated one. It should go away - - devices = NymeaCore::instance()->thingManager()->findConfiguredThings(autoMockThingClassId); - oldCount = devices.count(); - QVERIFY2(oldCount > 0, "There needs to be at least one auto-created Mock Device for this test"); - device = devices.first(); - - // trigger disappear signal in mock device - spy.clear(); - port = device->paramValue(autoMockThingHttpportParamTypeId).toInt(); - request.setUrl(QUrl(QString("http://localhost:%1/disappear").arg(port))); - reply = nam->get(request); - - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - - // Make sure one mock device has disappeared - QCOMPARE(NymeaCore::instance()->thingManager()->findConfiguredThings(autoMockThingClassId).count(), oldCount - 1); -} - -void TestDevices::testBrowsing_data() -{ - QTest::addColumn("deviceId"); - - QTest::newRow("regular mock device") << DeviceId(m_mockThingId); - QTest::newRow("async mock device") << DeviceId(m_mockThingAsyncId); -} - -void TestDevices::testBrowsing() -{ - QFETCH(DeviceId, deviceId); - - // Check if mockdevice is browsable - QVariant response = injectAndWait("Devices.GetSupportedDevices"); - - QVariantMap mockDeviceClass; - foreach (const QVariant &deviceClassVariant, response.toMap().value("params").toMap().value("deviceClasses").toList()) { - if (ThingClassId(deviceClassVariant.toMap().value("id").toString()) == mockThingClassId) { - mockDeviceClass = deviceClassVariant.toMap(); - } - } - - QVERIFY2(ThingClassId(mockDeviceClass.value("id").toString()) == mockThingClassId, "Could not find mock device"); - QCOMPARE(mockDeviceClass.value("browsable").toBool(), true); - - - // Browse it - QVariantMap params; - params.insert("deviceId", deviceId); - response = injectAndWait("Devices.BrowseDevice", params); - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), QString("DeviceErrorNoError")); - QVariantList browserEntries = response.toMap().value("params").toMap().value("items").toList(); - QVERIFY2(browserEntries.count() > 0, "BrowseDevice did not return any items."); - - // Browse item 001, it should be a folder with 2 items - params.insert("itemId", "001"); - response = injectAndWait("Devices.BrowseDevice", params); - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), QString("DeviceErrorNoError")); - browserEntries = response.toMap().value("params").toMap().value("items").toList(); - QVERIFY2(browserEntries.count() == 2, "BrowseDevice did not return 2 items as childs in folder with id 001."); - - // Browse a non-existent item - params["itemId"] = "this-does-not-exist"; - response = injectAndWait("Devices.BrowseDevice", params); - browserEntries = response.toMap().value("params").toMap().value("items").toList(); - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), QString("DeviceErrorItemNotFound")); - QCOMPARE(browserEntries.count(), 0); - - -} - -void TestDevices::discoverDeviceParenting() -{ - // Try to discover a mock child device. We don't have a mockParent yet, so it should fail - ThingDiscoveryInfo *discoveryInfo = NymeaCore::instance()->thingManager()->discoverThings(childMockThingClassId, ParamList()); - { - QSignalSpy spy(discoveryInfo, &ThingDiscoveryInfo::finished); - spy.wait(); - } - QVERIFY(discoveryInfo->thingDescriptors().count() == 0); - - - // Now create a mock parent by discovering... - discoveryInfo = NymeaCore::instance()->thingManager()->discoverThings(parentMockThingClassId, ParamList()); - { - QSignalSpy spy(discoveryInfo, &ThingDiscoveryInfo::finished); - spy.wait(); - } - QVERIFY(discoveryInfo->thingDescriptors().count() == 1); - ThingDescriptorId descriptorId = discoveryInfo->thingDescriptors().first().id(); - - QSignalSpy addSpy(NymeaCore::instance()->thingManager(), &ThingManager::thingAdded); - ThingSetupInfo *setupInfo = NymeaCore::instance()->thingManager()->addConfiguredThing(descriptorId, ParamList(), "Mock Parent (Discovered)"); - { - QSignalSpy spy(setupInfo, &ThingSetupInfo::finished); - spy.wait(); - } - QCOMPARE(setupInfo->status(), Thing::ThingErrorNoError); - - addSpy.wait(); - QCOMPARE(addSpy.count(), 2); // Mock device parent will also auto-create a child instantly - - Thing *parentDevice = addSpy.at(0).first().value(); - qCDebug(dcTests()) << "Added device:" << parentDevice->name(); - QVERIFY(parentDevice->thingClassId() == parentMockThingClassId); - - - // Ok we have our parent device, let's discover for childs again - discoveryInfo = NymeaCore::instance()->thingManager()->discoverThings(childMockThingClassId, ParamList()); - { - QSignalSpy spy(discoveryInfo, &ThingDiscoveryInfo::finished); - spy.wait(); - } - QVERIFY(discoveryInfo->thingDescriptors().count() == 1); - descriptorId = discoveryInfo->thingDescriptors().first().id(); - - // Found one! Adding it... - addSpy.clear(); - setupInfo = NymeaCore::instance()->thingManager()->addConfiguredThing(descriptorId, ParamList(), "Mock Child (Discovered)"); - { - QSignalSpy spy(setupInfo, &ThingSetupInfo::finished); - spy.wait(); - } - QCOMPARE(setupInfo->status(), Thing::ThingErrorNoError); - - QCOMPARE(addSpy.count(), 1); - - Thing *childDevice = addSpy.at(0).first().value(); - qCDebug(dcTests()) << "Added device:" << childDevice->name(); - QVERIFY(childDevice->thingClassId() == childMockThingClassId); - - // Now delete the parent and make sure the child will be deleted too - QSignalSpy removeSpy(NymeaCore::instance(), &NymeaCore::thingRemoved); - QPair > ret = NymeaCore::instance()->removeConfiguredThing(parentDevice->id(), QHash()); - QCOMPARE(ret.first, Thing::ThingErrorNoError); - QCOMPARE(removeSpy.count(), 3); // The parent, the auto-mock and the discovered mock - -} - -void TestDevices::testExecuteBrowserItem_data() -{ - QTest::addColumn("deviceId"); - QTest::addColumn("itemId"); - QTest::addColumn("deviceError"); - - QTest::newRow("regular mock device") << DeviceId(m_mockThingId) << "002" << "DeviceErrorNoError"; - QTest::newRow("regular mock device") << DeviceId(m_mockThingId) << "001" << "DeviceErrorItemNotExecutable"; - QTest::newRow("async mock device") << DeviceId(m_mockThingAsyncId) << "002" << "DeviceErrorNoError"; -} - -void TestDevices::testExecuteBrowserItem() -{ - QFETCH(DeviceId, deviceId); - QFETCH(QString, itemId); - QFETCH(QString, deviceError); - - QVariantMap params; - params.insert("deviceId", deviceId); - params.insert("itemId", itemId); - QVariant response = injectAndWait("Actions.ExecuteBrowserItem", params); - qCDebug(dcTests()) << "resp" << response; - - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), deviceError); -} - -void TestDevices::testExecuteBrowserItemAction_data() -{ - QTest::addColumn("deviceId"); - - QTest::newRow("regular mock device") << DeviceId(m_mockThingId); - QTest::newRow("async mock device") << DeviceId(m_mockThingAsyncId); -} - -void TestDevices::testExecuteBrowserItemAction() -{ - QFETCH(DeviceId, deviceId); - - QVariantMap getItemsParams; - getItemsParams.insert("deviceId", deviceId); - QVariant response = injectAndWait("Devices.BrowseDevice", getItemsParams); - QCOMPARE(response.toMap().value("status").toString(), QString("success")); - - QVariantList browserEntries = response.toMap().value("params").toMap().value("items").toList(); - QVERIFY(browserEntries.count() > 2); - - QVariantMap item002; // Find the item we need for this test - foreach (const QVariant &item, browserEntries) { - if (item.toMap().value("id").toString() == "002") { - item002 = item.toMap(); - break; - } - } - QVERIFY2(item002.value("id").toString() == QString("002"), "Item with context actions not found"); - QVERIFY2(item002.value("actionTypeIds").toList().count() > 0, "Item doesn't have actionTypeIds"); - QVERIFY2(ActionTypeId(item002.value("actionTypeIds").toList().first().toString()) == mockAddToFavoritesBrowserItemActionTypeId, "AddToFavorites action type id not found in item"); - - - // Browse favorites - // ID is "favorites" in mockDevice - // It should be ampty at this point - getItemsParams.insert("itemId", "favorites"); - response = injectAndWait("Devices.BrowseDevice", getItemsParams); - QCOMPARE(response.toMap().value("status").toString(), QString("success")); - - browserEntries = response.toMap().value("params").toMap().value("items").toList(); - QVERIFY2(browserEntries.count() == 0, "Favorites should be empty at this point"); - - // Now add an item to the favorites - QVariantMap actionParams; - actionParams.insert("deviceId", deviceId); - actionParams.insert("itemId", "002"); - actionParams.insert("actionTypeId", mockAddToFavoritesBrowserItemActionTypeId); - response = injectAndWait("Actions.ExecuteBrowserItemAction", actionParams); - QCOMPARE(response.toMap().value("status").toString(), QString("success")); - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), QString("DeviceErrorNoError")); - - // Fetch the list again - response = injectAndWait("Devices.BrowseDevice", getItemsParams); - QCOMPARE(response.toMap().value("status").toString(), QString("success")); - - browserEntries = response.toMap().value("params").toMap().value("items").toList(); - QCOMPARE(browserEntries.count(), 1); - - QString favoriteItemId = browserEntries.first().toMap().value("id").toString(); - QVERIFY2(!favoriteItemId.isEmpty(), "ItemId is empty in favorites list"); - - // Now remove the again from favorites - actionParams.clear(); - actionParams.insert("deviceId", deviceId); - actionParams.insert("itemId", favoriteItemId); - actionParams.insert("actionTypeId", mockRemoveFromFavoritesBrowserItemActionTypeId); - response = injectAndWait("Actions.ExecuteBrowserItemAction", actionParams); - QCOMPARE(response.toMap().value("status").toString(), QString("success")); - QCOMPARE(response.toMap().value("params").toMap().value("deviceError").toString(), QString("DeviceErrorNoError")); - - // Fetch the list again - response = injectAndWait("Devices.BrowseDevice", getItemsParams); - QCOMPARE(response.toMap().value("status").toString(), QString("success")); - - browserEntries = response.toMap().value("params").toMap().value("items").toList(); - QCOMPARE(browserEntries.count(), 0); - -} - -void TestDevices::executeAction_data() -{ - QTest::addColumn("deviceId"); - QTest::addColumn("actionTypeId"); - QTest::addColumn("actionParams"); - QTest::addColumn("error"); - - QVariantList params; - QVariantMap param1; - param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId); - param1.insert("value", 5); - params.append(param1); - QVariantMap param2; - param2.insert("paramTypeId", mockWithParamsActionParam2ParamTypeId); - param2.insert("value", true); - params.append(param2); - - QTest::newRow("valid action") << DeviceId(m_mockThingId) << mockWithParamsActionTypeId << params << Device::DeviceErrorNoError; - QTest::newRow("invalid deviceId") << DeviceId::createDeviceId() << mockWithParamsActionTypeId << params << Device::DeviceErrorDeviceNotFound; - QTest::newRow("invalid actionTypeId") << DeviceId(m_mockThingId) << ActionTypeId::createActionTypeId() << params << Device::DeviceErrorActionTypeNotFound; - QTest::newRow("missing params") << DeviceId(m_mockThingId) << mockWithParamsActionTypeId << QVariantList() << Device::DeviceErrorMissingParameter; - QTest::newRow("async action") << DeviceId(m_mockThingId) << mockAsyncActionTypeId << QVariantList() << Device::DeviceErrorNoError; - QTest::newRow("broken action") << DeviceId(m_mockThingId) << mockFailingActionTypeId << QVariantList() << Device::DeviceErrorSetupFailed; - QTest::newRow("async broken action") << DeviceId(m_mockThingId) << mockAsyncFailingActionTypeId << QVariantList() << Device::DeviceErrorSetupFailed; -} - -void TestDevices::executeAction() -{ - QFETCH(DeviceId, deviceId); - QFETCH(ActionTypeId, actionTypeId); - QFETCH(QVariantList, actionParams); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("actionTypeId", actionTypeId); - params.insert("deviceId", deviceId); - params.insert("params", actionParams); - QVariant response = injectAndWait("Devices.ExecuteAction", params); - qDebug() << "executeActionresponse" << response; - verifyError(response, "deviceError", enumValueName(error)); - - // Fetch action execution history from mock device - QNetworkAccessManager nam; - QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); - - QNetworkRequest request(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockThing1Port))); - QNetworkReply *reply = nam.get(request); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - QByteArray data = reply->readAll(); - - if (error == Device::DeviceErrorNoError) { - QVERIFY2(actionTypeId == ActionTypeId(data), QString("ActionTypeId mismatch. Got %1, Expected: %2") - .arg(ActionTypeId(data).toString()).arg(actionTypeId.toString()).toLatin1().data()); - } else { - QVERIFY2(data.length() == 0, QString("Data is %1, should be empty.").arg(QString(data)).toLatin1().data()); - } - - // cleanup for the next run - spy.clear(); - request.setUrl(QUrl(QString("http://localhost:%1/clearactionhistory").arg(m_mockThing1Port))); - reply = nam.get(request); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - - spy.clear(); - request.setUrl(QUrl(QString("http://localhost:%1/actionhistory").arg(m_mockThing1Port))); - reply = nam.get(request); - spy.wait(); - QCOMPARE(spy.count(), 1); - reply->deleteLater(); - data = reply->readAll(); - qDebug() << "cleared data:" << data; - -} - -void TestDevices::triggerEvent() -{ - enableNotifications({"Devices"}); - QList devices = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId); - QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test"); - Thing *device = devices.first(); - - - QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&))); - QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - // Setup connection to mock client - QNetworkAccessManager nam; - - // trigger event in mock device - int port = device->paramValue(mockThingHttpportParamTypeId).toInt(); - QNetworkRequest request(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(port).arg(mockEvent1EventTypeId.toString()))); - QNetworkReply *reply = nam.get(request); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - - // Lets wait for the notification - spy.wait(); - QVERIFY(spy.count() > 0); - for (int i = 0; i < spy.count(); i++ ){ - Event event = spy.at(i).at(0).value(); - if (event.thingId() == device->id()) { - // Make sure the event contains all the stuff we expect - QCOMPARE(event.eventTypeId(), mockEvent1EventTypeId); - } - } - - // Check for the notification on JSON API - QVariantList notifications; - notifications = checkNotifications(notificationSpy, "Devices.EventTriggered"); - QVERIFY2(notifications.count() == 1, QString("Should get Devices.EventTriggered notification but got: %1").arg(qUtf8Printable(QJsonDocument::fromVariant(notifications).toJson())).toUtf8()); - QVariantMap notificationContent = notifications.first().toMap().value("params").toMap(); - - QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString()); - QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockEvent1EventTypeId.toString()); -} - -void TestDevices::triggerStateChangeEvent() -{ - enableNotifications({"Devices"}); - - QList devices = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId); - QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test"); - Thing *device = devices.first(); - - QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&))); - QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - // Setup connection to mock client - QNetworkAccessManager nam; - - // trigger state changed event in mock device - int port = device->paramValue(mockThingHttpportParamTypeId).toInt(); - QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockIntStateTypeId.toString()).arg(11))); - QNetworkReply *reply = nam.get(request); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - - // Lets wait for the notification - spy.wait(); - QVERIFY(spy.count() > 0); - for (int i = 0; i < spy.count(); i++ ){ - Event event = spy.at(i).at(0).value(); - if (event.thingId() == device->id()) { - // Make sure the event contains all the stuff we expect - QCOMPARE(event.eventTypeId().toString(), mockIntStateTypeId.toString()); - QCOMPARE(event.param(ParamTypeId(mockIntStateTypeId.toString())).value().toInt(), 11); - } - } - - // Check for the notification on JSON API - QVariantList notifications; - notifications = checkNotifications(notificationSpy, "Devices.EventTriggered"); - QVERIFY2(notifications.count() == 1, "Should get Devices.EventTriggered notification"); - QVariantMap notificationContent = notifications.first().toMap().value("params").toMap(); - - QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString()); - QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockIntEventTypeId.toString()); - -} - -void TestDevices::params() -{ - Event event; - ParamList params; - ParamTypeId id = ParamTypeId::createParamTypeId(); - Param p(id, "foo bar"); - params.append(p); - event.setParams(params); - - QVERIFY(event.param(id).value().toString() == "foo bar"); - QVERIFY(!event.param(ParamTypeId::createParamTypeId()).value().isValid()); -} - -void TestDevices::asyncSetupEmitsSetupStatusUpdate() -{ - QVariantMap configuredDevices = injectAndWait("Devices.GetConfiguredDevices").toMap(); - foreach (const QVariant &deviceVariant, configuredDevices.value("params").toMap().value("devices").toList()) { - QVariantMap device = deviceVariant.toMap(); - qCDebug(dcTests()) << "confdiguredd device" << device.value("setupStatus"); - } - - // Restart the core instance to check if settings are loaded at startup - restartServer(); - enableNotifications({"Devices"}); - - QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - configuredDevices = injectAndWait("Devices.GetConfiguredDevices").toMap(); - QList devicesWithSetupInProgress; - foreach (const QVariant &deviceVariant, configuredDevices.value("params").toMap().value("devices").toList()) { - QVariantMap device = deviceVariant.toMap(); - qCDebug(dcTests()) << "Configured device" << device.value("name").toString() << "with setup status" << device.value("setupStatus").toString(); - if (device.value("setupStatus").toString() == "ThingSetupStatusInProgress") { - devicesWithSetupInProgress << device.value("id").toUuid(); - } - } - QVERIFY2(devicesWithSetupInProgress.count() > 0, "This test requires at least one device that is still being set up at this point."); - - QDateTime maxTime = QDateTime::currentDateTime().addSecs(10); - while (QDateTime::currentDateTime() < maxTime && devicesWithSetupInProgress.count() > 0) { - QList> notifications = notificationSpy; - while (notifications.count() > 0) { - QByteArray notificationData = notifications.takeFirst().at(1).toByteArray(); - QVariantMap notification = QJsonDocument::fromJson(notificationData).toVariant().toMap(); - if (notification.value("notification").toString() == "Devices.DeviceChanged") { - QString setupStatus = notification.value("params").toMap().value("device").toMap().value("setupStatus").toString(); - if (setupStatus == "ThingSetupStatusComplete") { - qCDebug(dcTests()) << "Device setup completed for" << notification.value("params").toMap().value("device").toMap().value("name").toString(); - DeviceId deviceId = notification.value("params").toMap().value("device").toMap().value("id").toUuid(); - devicesWithSetupInProgress.removeAll(deviceId); - } - } - } - notificationSpy.clear(); - if (devicesWithSetupInProgress.count() > 0) { - notificationSpy.wait(); - } - } - - QVERIFY2(devicesWithSetupInProgress.isEmpty(), "Some devices did not finish the setup!"); -} - -#include "testdevices.moc" -QTEST_MAIN(TestDevices) - diff --git a/tests/auto/events/events.pro b/tests/auto/events/events.pro deleted file mode 100644 index 8bbd7556..00000000 --- a/tests/auto/events/events.pro +++ /dev/null @@ -1,5 +0,0 @@ -include(../../../nymea.pri) -include(../autotests.pri) - -TARGET = testevents -SOURCES += testevents.cpp diff --git a/tests/auto/events/testevents.cpp b/tests/auto/events/testevents.cpp deleted file mode 100644 index 1dea52a1..00000000 --- a/tests/auto/events/testevents.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "nymeatestbase.h" -#include "nymeacore.h" - -#include "jsonrpc/devicehandler.h" -#include "servers/mocktcpserver.h" - -using namespace nymeaserver; - -class TestEvents: public NymeaTestBase -{ - Q_OBJECT - -private slots: - void triggerEvent(); - void triggerStateChangeEvent(); - - void params(); - - void getEventType_data(); - void getEventType(); -}; - -void TestEvents::triggerEvent() -{ - enableNotifications({"Events"}); - - QList devices = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId); - QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test"); - Thing *device = devices.first(); - - QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&))); - QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - // Setup connection to mock client - QNetworkAccessManager nam; - - // trigger event in mock device - int port = device->paramValue(mockThingHttpportParamTypeId).toInt(); - QNetworkRequest request(QUrl(QString("http://localhost:%1/generateevent?eventtypeid=%2").arg(port).arg(mockEvent1EventTypeId.toString()))); - QNetworkReply *reply = nam.get(request); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - - // Lets wait for the notification - spy.wait(); - QVERIFY(spy.count() > 0); - for (int i = 0; i < spy.count(); i++ ){ - Event event = spy.at(i).at(0).value(); - if (event.thingId() == device->id()) { - // Make sure the event contains all the stuff we expect - QCOMPARE(event.eventTypeId(), mockEvent1EventTypeId); - } - } - - // Check for the notification on JSON API - QVariantList notifications; - notifications = checkNotifications(notificationSpy, "Events.EventTriggered"); - QVERIFY2(notifications.count() == 1, "Should get Events.EventTriggered notification"); - QVERIFY2(notifications.first().toMap().contains("deprecationWarning"), "Deprecation warning not included in notification"); - - QVariantMap notificationContent = notifications.first().toMap().value("params").toMap(); - QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString()); - QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockEvent1EventTypeId.toString()); -} - -void TestEvents::triggerStateChangeEvent() -{ - enableNotifications({"Events"}); - - QList devices = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId); - QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test"); - Thing *device = devices.first(); - - QSignalSpy spy(NymeaCore::instance(), SIGNAL(eventTriggered(const Event&))); - QSignalSpy notificationSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); - - // Setup connection to mock client - QNetworkAccessManager nam; - - // trigger state changed event in mock device - int port = device->paramValue(mockThingHttpportParamTypeId).toInt(); - QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockIntStateTypeId.toString()).arg(11))); - QNetworkReply *reply = nam.get(request); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - - // Lets wait for the notification - spy.wait(); - QVERIFY(spy.count() > 0); - for (int i = 0; i < spy.count(); i++ ){ - Event event = spy.at(i).at(0).value(); - if (event.thingId() == device->id()) { - // Make sure the event contains all the stuff we expect - QCOMPARE(event.eventTypeId().toString(), mockIntStateTypeId.toString()); - QCOMPARE(event.param(ParamTypeId(mockIntStateTypeId.toString())).value().toInt(), 11); - } - } - - // Check for the notification on JSON API - QVariantList notifications; - notifications = checkNotifications(notificationSpy, "Events.EventTriggered"); - QVERIFY2(notifications.count() == 1, "Should get Devices.EventTriggered notification"); - QVERIFY2(notifications.first().toMap().contains("deprecationWarning"), "Deprecation warning not included in notification!"); - - QVariantMap notificationContent = notifications.first().toMap().value("params").toMap(); - - QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), device->id().toString()); - QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockIntEventTypeId.toString()); -} - -void TestEvents::params() -{ - Event event; - ParamList params; - ParamTypeId id = ParamTypeId::createParamTypeId(); - Param p(id, "foo bar"); - params.append(p); - event.setParams(params); - - QVERIFY(event.param(id).value().toString() == "foo bar"); - QVERIFY(!event.param(ParamTypeId::createParamTypeId()).value().isValid()); -} - -void TestEvents::getEventType_data() -{ - QTest::addColumn("eventTypeId"); - QTest::addColumn("error"); - - QTest::newRow("valid eventypeid") << mockEvent1EventTypeId << Device::DeviceErrorNoError; - QTest::newRow("invalid eventypeid") << EventTypeId::createEventTypeId() << Device::DeviceErrorEventTypeNotFound; -} - -void TestEvents::getEventType() -{ - QFETCH(EventTypeId, eventTypeId); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("eventTypeId", eventTypeId.toString()); - QVariant response = injectAndWait("Events.GetEventType", params); - - verifyError(response, "deviceError", enumValueName(error)); - - qCDebug(dcTests()) << "*content" << response; - QVERIFY2(response.toMap().contains("deprecationWarning"), "Deprecation warning not shown in reply"); - - if (error == Device::DeviceErrorNoError) { - QVERIFY2(EventTypeId(response.toMap().value("params").toMap().value("eventType").toMap().value("id").toString()) == eventTypeId, "Didn't get a reply for the same actionTypeId as requested."); - } -} - -#include "testevents.moc" -QTEST_MAIN(TestEvents) diff --git a/tests/auto/integrations/testintegrations.cpp b/tests/auto/integrations/testintegrations.cpp index 71f32cb0..36f1a1ac 100644 --- a/tests/auto/integrations/testintegrations.cpp +++ b/tests/auto/integrations/testintegrations.cpp @@ -84,6 +84,8 @@ private slots: void storedThings(); + void stateCache(); + void discoverThings_data(); void discoverThings(); @@ -650,6 +652,74 @@ void TestIntegrations::storedThings() verifyThingError(response); } +void TestIntegrations::stateCache() +{ + ThingClass mockThingClass = NymeaCore::instance()->thingManager()->findThingClass(mockThingClassId); + + QVERIFY2(mockThingClass.getStateType(mockIntStateTypeId).cached(), "Mock int state is not cached (required to be true for this test)"); + QVERIFY2(!mockThingClass.getStateType(mockBoolStateTypeId).cached(), "Mock bool state is cached (required to be false for this test)"); + + Thing* thing = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId).first(); + int port = thing->paramValue(mockThingHttpportParamTypeId).toInt(); + QNetworkAccessManager nam; + QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); + + + // First set the state values to something that is *not* the default + int oldIntValue = mockThingClass.getStateType(mockIntStateTypeId).defaultValue().toInt(); + int newIntValue = oldIntValue + 1; + bool oldBoolValue = mockThingClass.getStateType(mockBoolStateTypeId).defaultValue().toBool(); + bool newBoolValue = !oldBoolValue; + + QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockIntStateTypeId.toString()).arg(newIntValue))); + QNetworkReply *reply = nam.get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + spy.wait(); + + spy.clear(); + request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockBoolStateTypeId.toString()).arg(newBoolValue))); + reply = nam.get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + spy.wait(); + + // For completeness, verify through JSONRPC that they were actually yet. + QVariantMap params; + params.insert("thingId", thing->id()); + + params["stateTypeId"] = mockIntStateTypeId; + QVariant response = injectAndWait("Integrations.GetStateValue", params); + QCOMPARE(response.toMap().value("params").toMap().value("value").toInt(), newIntValue); + + params["stateTypeId"] = mockBoolStateTypeId; + response = injectAndWait("Integrations.GetStateValue", params); + QCOMPARE(response.toMap().value("params").toMap().value("value").toBool(), newBoolValue); + + // Restart the server + restartServer(); + + // And check if the cached int state has successfully been restored + params["stateTypeId"] = mockIntStateTypeId; + response = injectAndWait("Integrations.GetStateValue", params); + QCOMPARE(response.toMap().value("params").toMap().value("value").toInt(), newIntValue); + + // and that the non-cached bool state is back to its default + params["stateTypeId"] = mockBoolStateTypeId; + response = injectAndWait("Integrations.GetStateValue", params); + QCOMPARE(response.toMap().value("params").toMap().value("value").toBool(), mockThingClass.getStateType(mockBoolStateTypeId).defaultValue().toBool()); + + // Reset back to default values + spy.clear(); + request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockBoolStateTypeId.toString()).arg(oldIntValue))); + reply = nam.get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + spy.wait(); + spy.clear(); + request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockBoolStateTypeId.toString()).arg(oldBoolValue))); + reply = nam.get(request); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + spy.wait(); +} + void TestIntegrations::discoverThings_data() { QTest::addColumn("thingClassId"); @@ -1011,6 +1081,7 @@ void TestIntegrations::getStateValue_data() void TestIntegrations::getStateValue() { + NymeaCore::instance()->thingManager()->findConfiguredThing(m_mockThingId)->setStateValue(mockIntStateTypeId, 10); QFETCH(ThingId, thingId); QFETCH(StateTypeId, stateTypeId); QFETCH(Thing::ThingError, statusCode); @@ -2085,7 +2156,7 @@ void TestIntegrations::triggerStateChangeEvent() // trigger state changed event in mock device int port = thing->paramValue(mockThingHttpportParamTypeId).toInt(); - QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockIntStateTypeId.toString()).arg(11))); + QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockIntStateTypeId.toString()).arg(37))); QNetworkReply *reply = nam.get(request); connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); @@ -2097,7 +2168,7 @@ void TestIntegrations::triggerStateChangeEvent() if (event.thingId() == thing->id()) { // Make sure the event contains all the stuff we expect QCOMPARE(event.eventTypeId().toString(), mockIntStateTypeId.toString()); - QCOMPARE(event.param(ParamTypeId(mockIntStateTypeId.toString())).value().toInt(), 11); + QCOMPARE(event.param(ParamTypeId(mockIntStateTypeId.toString())).value().toInt(), 37); } } @@ -2107,7 +2178,7 @@ void TestIntegrations::triggerStateChangeEvent() QVERIFY2(notifications.count() == 1, "Should get Integrations.EventTriggered notification"); QVariantMap notificationContent = notifications.first().toMap().value("params").toMap(); - QCOMPARE(notificationContent.value("event").toMap().value("deviceId").toUuid().toString(), thing->id().toString()); + QCOMPARE(notificationContent.value("event").toMap().value("thingId").toUuid().toString(), thing->id().toString()); QCOMPARE(notificationContent.value("event").toMap().value("eventTypeId").toUuid().toString(), mockIntEventTypeId.toString()); } diff --git a/tests/auto/jsonrpc/testjsonrpc.cpp b/tests/auto/jsonrpc/testjsonrpc.cpp index ddafd3c0..eb2ce9dc 100644 --- a/tests/auto/jsonrpc/testjsonrpc.cpp +++ b/tests/auto/jsonrpc/testjsonrpc.cpp @@ -150,8 +150,7 @@ QStringList TestJSONRPC::extractRefs(const QVariant &variant) void TestJSONRPC::initTestCase() { NymeaDBusService::setBusType(QDBusConnection::SessionBus); - NymeaTestBase::initTestCase(); - QLoggingCategory::setFilterRules("*.debug=false\n" + NymeaTestBase::initTestCase("*.debug=false\n" // "JsonRpcTraffic.debug=true\n" "JsonRpc.debug=true\n" "Translations.debug=true\n" @@ -674,7 +673,7 @@ void TestJSONRPC::enableDisableNotifications_legacy() QStringList expectedNamespaces; if (enabled == "true") { - expectedNamespaces << "Actions" << "NetworkManager" << "Devices" << "Integrations" << "System" << "Rules" << "States" << "Logging" << "Tags" << "AppData" << "JSONRPC" << "Configuration" << "Events" << "Scripts" << "Users" << "Zigbee" << "ModbusRtu"; + expectedNamespaces << "NetworkManager" << "Integrations" << "System" << "Rules"<< "Logging" << "Tags" << "AppData" << "JSONRPC" << "Configuration" << "Scripts" << "Users" << "Zigbee" << "ModbusRtu"; } std::sort(expectedNamespaces.begin(), expectedNamespaces.end()); @@ -700,7 +699,6 @@ void TestJSONRPC::ruleAddedRemovedNotifications() QVariantMap stateDescriptor; stateDescriptor.insert("stateTypeId", mockIntStateTypeId); stateDescriptor.insert("thingId", m_mockThingId); - stateDescriptor.insert("deviceId", m_mockThingId); // DEPRECATED stateDescriptor.insert("operator", enumValueName(Types::ValueOperatorLess)); stateDescriptor.insert("value", "20"); // This is a bit odd: QUuid.toString() wraps the uuids in {}, however, the implicit cast doesn't @@ -715,7 +713,6 @@ void TestJSONRPC::ruleAddedRemovedNotifications() QVariantMap actionNoParams; actionNoParams.insert("actionTypeId", mockWithoutParamsActionTypeId); actionNoParams.insert("thingId", m_mockThingId); - actionNoParams.insert("deviceId", m_mockThingId); // DEPRECATED // This is a bit odd: QUuid.toString() wraps the uuids in {}, however, the implicit cast doesn't // .toString(QUuid::WithoutBraces) has only been added in 5.11 so we can't use that either... // Only hack I can come up with right now is to convert it to a Json and back to use the implicit cast @@ -725,7 +722,6 @@ void TestJSONRPC::ruleAddedRemovedNotifications() QVariantMap eventDescriptor; eventDescriptor.insert("eventTypeId", mockEvent1EventTypeId); eventDescriptor.insert("thingId", m_mockThingId); - eventDescriptor.insert("deviceId", m_mockThingId); // DEPRECATED // This is a bit odd: QUuid.toString() wraps the uuids in {}, however, the implicit cast doesn't // .toString(QUuid::WithoutBraces) has only been added in 5.11 so we can't use that either... // Only hack I can come up with right now is to convert it to a Json and back to use the implicit cast @@ -789,7 +785,6 @@ void TestJSONRPC::ruleActiveChangedNotifications() QVariantMap stateDescriptor; stateDescriptor.insert("stateTypeId", mockIntStateTypeId); stateDescriptor.insert("thingId", m_mockThingId); - stateDescriptor.insert("deviceId", m_mockThingId); // DEPRECATED stateDescriptor.insert("operator", enumValueName(Types::ValueOperatorEquals)); stateDescriptor.insert("value", "20"); // This is a bit odd: QUuid.toString() wraps the uuids in {}, however, the implicit cast doesn't @@ -804,7 +799,6 @@ void TestJSONRPC::ruleActiveChangedNotifications() QVariantMap actionNoParams; actionNoParams.insert("actionTypeId", mockWithoutParamsActionTypeId); actionNoParams.insert("thingId", m_mockThingId); - actionNoParams.insert("deviceId", m_mockThingId); // DEPRECATED // This is a bit odd: QUuid.toString() wraps the uuids in {}, however, the implicit cast doesn't // .toString(QUuid::WithoutBraces) has only been added in 5.11 so we can't use that either... // Only hack I can come up with right now is to convert it to a Json and back to use the implicit cast @@ -855,21 +849,18 @@ void TestJSONRPC::ruleActiveChangedNotifications() spy.clear(); clientSpy.clear(); // set the rule inactive - qDebug() << "setting mock int state to 42"; + qCDebug(dcTests) << "setting mock int state to 42"; QNetworkRequest request2(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(m_mockThing1Port).arg(mockIntStateTypeId.toString()).arg(42))); QNetworkReply *reply2 = nam.get(request2); connect(reply2, SIGNAL(finished()), reply2, SLOT(deleteLater())); // Waiting for notifications: - // Devices.StateChanged for the change we did - // Devices.EventTriggered - // Events.EventTriggered <-- deprecated + // Integrations.StateChanged for the change we did + // Integrations.EventTriggered // Rules.RuleActiveChanged - // Logging.LogEntryAdded - // Devices.StateChanged for the change done by the rule - // Devices.EventTriggered - // Events.EventTriggered <-- deprecated - while (clientSpy.count() < 8) { + // Logging.LogEntryAdded // One for the state change we did + // Logging.LogEntryAdded // One for the rule state change + while (clientSpy.count() < 5) { clientSpy.wait(); } @@ -894,7 +885,7 @@ void TestJSONRPC::ruleActiveChangedNotifications() void TestJSONRPC::stateChangeEmitsNotifications() { - enableNotifications({"Devices", "States", "Logging", "Events"}); + enableNotifications({"Integrations", "Logging"}); bool found = false; // Setup connection to mock client @@ -911,9 +902,9 @@ void TestJSONRPC::stateChangeEmitsNotifications() if (replySpy.count() == 0) replySpy.wait(); // Make sure the notification contains all the stuff we expect - QVariantList stateChangedVariants = checkNotifications(clientSpy, "Devices.StateChanged"); - QVERIFY2(!stateChangedVariants.isEmpty(), "Did not get Devices.StateChanged notification."); - qDebug() << "got" << stateChangedVariants.count() << "Devices.StateChanged notifications"; + QVariantList stateChangedVariants = checkNotifications(clientSpy, "Integrations.StateChanged"); + QVERIFY2(!stateChangedVariants.isEmpty(), "Did not get Integrations.StateChanged notification."); + qDebug() << "got" << stateChangedVariants.count() << "Integrations.StateChanged notifications"; foreach (const QVariant &stateChangedVariant, stateChangedVariants) { if (stateChangedVariant.toMap().value("params").toMap().value("stateTypeId").toUuid() == stateTypeId) { found = true; @@ -933,8 +924,8 @@ void TestJSONRPC::stateChangeEmitsNotifications() } // Make sure the notification contains all the stuff we expect - QVariantList eventTriggeredVariants = checkNotifications(clientSpy, "Events.EventTriggered"); - QVERIFY2(!eventTriggeredVariants.isEmpty(), "Did not get Events.EventTriggered notification."); + QVariantList eventTriggeredVariants = checkNotifications(clientSpy, "Integrations.EventTriggered"); + QVERIFY2(!eventTriggeredVariants.isEmpty(), "Did not get Integrations.EventTriggered notification."); found = false; foreach (const QVariant &eventTriggeredVariant, eventTriggeredVariants) { if (eventTriggeredVariant.toMap().value("params").toMap().value("event").toMap().value("eventTypeId").toUuid() == stateTypeId) { @@ -944,7 +935,7 @@ void TestJSONRPC::stateChangeEmitsNotifications() } } - QVERIFY2(found, "Could not find the corresponding Events.EventTriggered notification"); + QVERIFY2(found, "Could not find the corresponding Integrations.EventTriggered notification"); // Now turn off notifications QCOMPARE(disableNotifications(), true); diff --git a/tests/auto/logging/testlogging.cpp b/tests/auto/logging/testlogging.cpp index 9c9ac62a..c6a6614b 100644 --- a/tests/auto/logging/testlogging.cpp +++ b/tests/auto/logging/testlogging.cpp @@ -300,7 +300,7 @@ void TestLogging::eventLogs() // Now snoop in for the events clearLoggingDatabase(); - enableNotifications({"Events", "Logging"}); + enableNotifications({"Integrations", "Logging"}); QSignalSpy clientSpy(m_mockTcpServer, SIGNAL(outgoingData(QUuid,QByteArray))); // trigger state change in mock device diff --git a/tests/auto/rules/testrules.cpp b/tests/auto/rules/testrules.cpp index 94ff1c6e..462e04d2 100644 --- a/tests/auto/rules/testrules.cpp +++ b/tests/auto/rules/testrules.cpp @@ -422,7 +422,6 @@ void TestRules::addRemoveRules_data() QVariantMap validActionNoParams; validActionNoParams.insert("actionTypeId", mockWithoutParamsActionTypeId); validActionNoParams.insert("thingId", m_mockThingId); - validActionNoParams.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap invalidAction; invalidAction.insert("actionTypeId", ActionTypeId("f32c7efb-38b6-4576-a496-c75bbb23132f")); @@ -432,7 +431,6 @@ void TestRules::addRemoveRules_data() QVariantMap validExitActionNoParams; validExitActionNoParams.insert("actionTypeId", mockWithoutParamsActionTypeId); validExitActionNoParams.insert("thingId", m_mockThingId); - validExitActionNoParams.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap invalidExitAction; invalidExitAction.insert("actionTypeId", ActionTypeId("f32c7efb-38b6-4576-a496-c75bbb23132f")); @@ -458,12 +456,10 @@ void TestRules::addRemoveRules_data() QVariantMap validEventDescriptor1; validEventDescriptor1.insert("eventTypeId", mockEvent1EventTypeId); validEventDescriptor1.insert("thingId", m_mockThingId); - validEventDescriptor1.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap validEventDescriptor2; validEventDescriptor2.insert("eventTypeId", mockEvent2EventTypeId); validEventDescriptor2.insert("thingId", m_mockThingId); - validEventDescriptor2.insert("deviceId", m_mockThingId); // DEPRECATED QVariantList params; QVariantMap param1; @@ -476,7 +472,6 @@ void TestRules::addRemoveRules_data() QVariantMap validEventDescriptor3; validEventDescriptor3.insert("eventTypeId", mockEvent2EventTypeId); validEventDescriptor3.insert("thingId", m_mockThingId); - validEventDescriptor3.insert("deviceId", m_mockThingId); // DREPECATED // EventDescriptorList QVariantList eventDescriptorList; @@ -491,7 +486,6 @@ void TestRules::addRemoveRules_data() QVariantMap validActionEventBased; validActionEventBased.insert("actionTypeId", mockWithParamsActionTypeId); validActionEventBased.insert("thingId", m_mockThingId); - validActionEventBased.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap validActionEventBasedParam1; validActionEventBasedParam1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId); validActionEventBasedParam1.insert("eventTypeId", mockEvent2EventTypeId); @@ -675,7 +669,6 @@ void TestRules::editRules_data() QVariantMap validActionNoParams; validActionNoParams.insert("actionTypeId", mockWithoutParamsActionTypeId); validActionNoParams.insert("thingId", m_mockThingId); - validActionNoParams.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap invalidAction; invalidAction.insert("actionTypeId", ActionTypeId()); @@ -685,7 +678,6 @@ void TestRules::editRules_data() QVariantMap validExitActionNoParams; validExitActionNoParams.insert("actionTypeId", mockWithoutParamsActionTypeId); validExitActionNoParams.insert("thingId", m_mockThingId); - validExitActionNoParams.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap invalidExitAction; invalidExitAction.insert("actionTypeId", ActionTypeId()); @@ -711,12 +703,10 @@ void TestRules::editRules_data() QVariantMap validEventDescriptor1; validEventDescriptor1.insert("eventTypeId", mockEvent1EventTypeId); validEventDescriptor1.insert("thingId", m_mockThingId); - validEventDescriptor1.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap validEventDescriptor2; validEventDescriptor2.insert("eventTypeId", mockEvent2EventTypeId); validEventDescriptor2.insert("thingId", m_mockThingId); - validEventDescriptor2.insert("deviceId", m_mockThingId); // DEPRECATED QVariantList params; QVariantMap param1; param1.insert("paramTypeId", mockEvent2EventIntParamParamTypeId); @@ -728,7 +718,6 @@ void TestRules::editRules_data() QVariantMap validEventDescriptor3; validEventDescriptor3.insert("eventTypeId", mockEvent2EventTypeId); validEventDescriptor3.insert("thingId", m_mockThingId); - validEventDescriptor3.insert("deviceId", m_mockThingId); // DEPRECATED // EventDescriptorList QVariantList eventDescriptorList; @@ -743,7 +732,6 @@ void TestRules::editRules_data() QVariantMap validActionEventBased; validActionEventBased.insert("actionTypeId", mockWithParamsActionTypeId); validActionEventBased.insert("thingId", m_mockThingId); - validActionEventBased.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap validActionEventBasedParam1; validActionEventBasedParam1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId); validActionEventBasedParam1.insert("eventTypeId", mockEvent2EventTypeId); @@ -828,11 +816,9 @@ void TestRules::editRules() QVariantMap eventDescriptor1; eventDescriptor1.insert("eventTypeId", mockEvent1EventTypeId); eventDescriptor1.insert("thingId", m_mockThingId); - eventDescriptor1.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap eventDescriptor2; eventDescriptor2.insert("eventTypeId", mockEvent2EventTypeId); eventDescriptor2.insert("thingId", m_mockThingId); - eventDescriptor2.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap eventParam1; eventParam1.insert("paramTypeId", mockEvent2EventIntParamParamTypeId); eventParam1.insert("value", 3); @@ -889,7 +875,6 @@ void TestRules::editRules() QVariantMap validActionEventBased; validActionEventBased.insert("actionTypeId", mockWithParamsActionTypeId); validActionEventBased.insert("thingId", m_mockThingId); - validActionEventBased.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap validActionEventBasedParam1; validActionEventBasedParam1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId); validActionEventBasedParam1.insert("eventTypeId", mockEvent2EventTypeId); @@ -903,7 +888,6 @@ void TestRules::editRules() QVariantMap validEventDescriptor3; validEventDescriptor3.insert("eventTypeId", mockEvent2EventTypeId); validEventDescriptor3.insert("thingId", m_mockThingId); - validEventDescriptor3.insert("deviceId", m_mockThingId); // DEPRECATED validEventDescriptor3.insert("paramDescriptors", QVariantList()); validEventDescriptors3.append(validEventDescriptor3); @@ -978,7 +962,7 @@ void TestRules::editRules() foreach (const QVariant &eventDescriptorVariant, eventDescriptorList) { bool found = false; foreach (const QVariant &replyEventDescriptorVariant, eventDescriptors) { - if (eventDescriptorVariant.toMap().value("deviceId") == replyEventDescriptorVariant.toMap().value("deviceId") && + if (eventDescriptorVariant.toMap().value("thingId") == replyEventDescriptorVariant.toMap().value("thingId") && eventDescriptorVariant.toMap().value("eventTypeId") == replyEventDescriptorVariant.toMap().value("eventTypeId")) { found = true; QVERIFY2(eventDescriptorVariant == replyEventDescriptorVariant, "Event descriptor doesn't match"); @@ -1135,12 +1119,10 @@ void TestRules::loadStoreConfig() QVariantMap eventDescriptor1; eventDescriptor1.insert("eventTypeId", mockEvent1EventTypeId); eventDescriptor1.insert("thingId", m_mockThingId); - eventDescriptor1.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap eventDescriptor2; eventDescriptor2.insert("eventTypeId", mockEvent2EventTypeId); eventDescriptor2.insert("thingId", m_mockThingId); - eventDescriptor2.insert("deviceId", m_mockThingId); // DEPRECATED QVariantList eventParamDescriptors; QVariantMap eventParam1; eventParam1.insert("paramTypeId", mockEvent2EventIntParamParamTypeId); @@ -1158,7 +1140,6 @@ void TestRules::loadStoreConfig() QVariantMap stateDescriptor2; stateDescriptor2.insert("thingId", m_mockThingId); - stateDescriptor2.insert("deviceId", m_mockThingId); // DEPRECATED stateDescriptor2.insert("operator", enumValueName(Types::ValueOperatorEquals)); stateDescriptor2.insert("stateTypeId", mockIntStateTypeId); stateDescriptor2.insert("value", 1); @@ -1168,7 +1149,6 @@ void TestRules::loadStoreConfig() QVariantMap stateDescriptor3; stateDescriptor3.insert("thingId", m_mockThingId); - stateDescriptor3.insert("deviceId", m_mockThingId); // DEPRECATED stateDescriptor3.insert("operator", enumValueName(Types::ValueOperatorEquals)); stateDescriptor3.insert("stateTypeId", mockBoolStateTypeId); stateDescriptor3.insert("value", true); @@ -1196,13 +1176,11 @@ void TestRules::loadStoreConfig() QVariantMap action1; action1.insert("actionTypeId", mockWithoutParamsActionTypeId); action1.insert("thingId", m_mockThingId); - action1.insert("deviceId", m_mockThingId); // DEPRECATED action1.insert("ruleActionParams", QVariantList()); QVariantMap action2; action2.insert("actionTypeId", mockWithParamsActionTypeId); action2.insert("thingId", m_mockThingId); - action2.insert("deviceId", m_mockThingId); // DEPRECATED QVariantList action2Params; QVariantMap action2Param1; action2Param1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId); @@ -1218,7 +1196,6 @@ void TestRules::loadStoreConfig() QVariantMap validActionEventBased; validActionEventBased.insert("actionTypeId", mockWithParamsActionTypeId); validActionEventBased.insert("thingId", m_mockThingId); - validActionEventBased.insert("deviceId", m_mockThingId); // DEPRECATED QVariantMap validActionEventBasedParam1; validActionEventBasedParam1.insert("paramTypeId", mockWithParamsActionParam1ParamTypeId); validActionEventBasedParam1.insert("eventTypeId", mockEvent2EventTypeId); @@ -1232,7 +1209,6 @@ void TestRules::loadStoreConfig() QVariantMap validEventDescriptor3; validEventDescriptor3.insert("eventTypeId", mockEvent2EventTypeId); validEventDescriptor3.insert("thingId", m_mockThingId); - validEventDescriptor3.insert("deviceId", m_mockThingId); // DEPRECATED validEventDescriptors3.append(validEventDescriptor3); // Interface based event descriptor @@ -1446,7 +1422,7 @@ void TestRules::loadStoreConfig() QVERIFY2(stateDescriptor.value("interface") == "battery", "Interface of stateDescriptor does not match"); QVERIFY2(stateDescriptor.value("interfaceState") == "batteryCritical", "InterfaceState of stateDescriptor doesn't match"); } else { - QVERIFY2(false, "StateDescriptor must have either deviceId/stateTypeId or interface/interfaceState."); + QVERIFY2(false, "StateDescriptor must have either thingId/stateTypeId or interface/interfaceState."); } } diff --git a/tests/auto/scripts/testscripts.cpp b/tests/auto/scripts/testscripts.cpp index 723e23dd..fa634403 100644 --- a/tests/auto/scripts/testscripts.cpp +++ b/tests/auto/scripts/testscripts.cpp @@ -99,11 +99,11 @@ void TestScripts::testScriptEventById() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceEvent {\n" - " deviceId: \"%1\"\n" + " ThingEvent {\n" + " thingId: \"%1\"\n" " eventTypeId: \"%2\"\n" " onTriggered: {\n" - " TestHelper.logEvent(deviceId, eventTypeId, params);\n" + " TestHelper.logEvent(thingId, eventTypeId, params);\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg(mockPowerEventTypeId.toString()); @@ -135,11 +135,11 @@ void TestScripts::testScriptEventByName() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceEvent {\n" - " deviceId: \"%1\"\n" + " ThingEvent {\n" + " thingId: \"%1\"\n" " eventName: \"%2\"\n" " onTriggered: {\n" - " TestHelper.logEvent(deviceId, eventName, params);\n" + " TestHelper.logEvent(thingId, eventName, params);\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg("power"); @@ -171,11 +171,11 @@ void TestScripts::testReadScriptStateById() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceState {\n" - " deviceId: \"%1\"\n" + " ThingState {\n" + " thingId: \"%1\"\n" " stateTypeId: \"%2\"\n" " onValueChanged: {\n" - " TestHelper.logStateChange(deviceId, stateTypeId, value);\n" + " TestHelper.logStateChange(thingId, stateTypeId, value);\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg(mockPowerStateTypeId.toString()); @@ -204,11 +204,11 @@ void TestScripts::testReadScriptStateByNyme() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceState {\n" - " deviceId: \"%1\"\n" + " ThingState {\n" + " thingId: \"%1\"\n" " stateName: \"%2\"\n" " onValueChanged: {\n" - " TestHelper.logStateChange(deviceId, stateName, value);\n" + " TestHelper.logStateChange(thingId, stateName, value);\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg("power"); @@ -237,15 +237,15 @@ void TestScripts::testWriteScriptStateById() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceState {\n" - " id: deviceState\n" - " deviceId: \"%1\"\n" + " ThingState {\n" + " id: thingState\n" + " thingId: \"%1\"\n" " stateTypeId: \"%2\"\n" " }\n" " Connections {\n" " target: TestHelper\n" " onSetState: {\n" - " deviceState.value = value\n" + " thingState.value = value\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg(mockPowerStateTypeId.toString()); @@ -271,15 +271,15 @@ void TestScripts::testWriteScriptStateByName() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceState {\n" - " id: deviceState\n" - " deviceId: \"%1\"\n" + " ThingState {\n" + " id: thingState\n" + " thingId: \"%1\"\n" " stateName: \"%2\"\n" " }\n" " Connections {\n" " target: TestHelper\n" " onSetState: {\n" - " deviceState.value = value\n" + " thingState.value = value\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg("power"); @@ -305,15 +305,15 @@ void TestScripts::testScriptActionById() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceAction {\n" - " id: deviceAction\n" - " deviceId: \"%1\"\n" + " ThingAction {\n" + " id: thingAction\n" + " thingId: \"%1\"\n" " actionTypeId: \"%2\"\n" " }\n" " Connections {\n" " target: TestHelper\n" " onExecuteAction: {\n" - " deviceAction.execute(params)\n" + " thingAction.execute(params)\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg(mockPowerActionTypeId.toString()); @@ -341,15 +341,15 @@ void TestScripts::testScriptActionByName() QString script = QString("import QtQuick 2.0\n" "import nymea 1.0\n" "Item {\n" - " DeviceAction {\n" - " id: deviceAction\n" - " deviceId: \"%1\"\n" + " ThingAction {\n" + " id: thingAction\n" + " thingId: \"%1\"\n" " actionName: \"%2\"\n" " }\n" " Connections {\n" " target: TestHelper\n" " onExecuteAction: {\n" - " deviceAction.execute(params)\n" + " thingAction.execute(params)\n" " }\n" " }\n" "}\n").arg(m_mockThingId.toString()).arg("power"); diff --git a/tests/auto/states/states.pro b/tests/auto/states/states.pro deleted file mode 100644 index 75d3caa4..00000000 --- a/tests/auto/states/states.pro +++ /dev/null @@ -1,5 +0,0 @@ -include(../../../nymea.pri) -include(../autotests.pri) - -TARGET = states -SOURCES += teststates.cpp diff --git a/tests/auto/states/teststates.cpp b/tests/auto/states/teststates.cpp deleted file mode 100644 index e92907c5..00000000 --- a/tests/auto/states/teststates.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -* -* Copyright 2013 - 2020, nymea GmbH -* Contact: contact@nymea.io -* -* This file is part of nymea. -* This project including source code and documentation is protected by -* copyright law, and remains the property of nymea GmbH. All rights, including -* reproduction, publication, editing and translation, are reserved. The use of -* this project is subject to the terms of a license agreement to be concluded -* with nymea GmbH in accordance with the terms of use of nymea GmbH, available -* under https://nymea.io/license -* -* GNU General Public License Usage -* Alternatively, this project may be redistributed and/or modified under the -* terms of the GNU General Public License as published by the Free Software -* Foundation, GNU version 3. This project is distributed in the hope that it -* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty -* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -* Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this project. If not, see . -* -* For any further details and any questions please contact us under -* contact@nymea.io or see our FAQ/Licensing Information on -* https://nymea.io/license/faq -* -* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "nymeatestbase.h" -#include "nymeacore.h" -#include "jsonrpc/devicehandler.h" - -using namespace nymeaserver; - -class TestStates: public NymeaTestBase -{ - Q_OBJECT - -private slots: - void getStateTypes(); - - void getStateValue_data(); - void getStateValue(); - - void save_load_states(); -}; - -void TestStates::getStateTypes() -{ - QVariantMap params; - params.insert("deviceClassId", mockThingClassId); - QVariant response = injectAndWait("Devices.GetStateTypes", params); - QVERIFY(!response.isNull()); - //verifyDeviceError(response); -} - -void TestStates::getStateValue_data() -{ - QList devices = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId); - QVERIFY2(devices.count() > 0, "There needs to be at least one configured Mock Device for this test"); - Thing *device = devices.first(); - - QTest::addColumn("deviceId"); - QTest::addColumn("stateTypeId"); - QTest::addColumn("error"); - - QTest::newRow("existing state") << device->id() << mockIntStateTypeId << Device::DeviceErrorNoError; - QTest::newRow("invalid device") << ThingId::createThingId() << mockIntStateTypeId << Device::DeviceErrorDeviceNotFound; - QTest::newRow("invalid statetype") << device->id() << StateTypeId::createStateTypeId() << Device::DeviceErrorStateTypeNotFound; -} - -void TestStates::getStateValue() -{ - QFETCH(ThingId, deviceId); - QFETCH(StateTypeId, stateTypeId); - QFETCH(Device::DeviceError, error); - - QVariantMap params; - params.insert("deviceId", deviceId.toString()); - params.insert("stateTypeId", stateTypeId.toString()); - - QVariant response = injectAndWait("Devices.GetStateValue", params); - - verifyError(response, "deviceError", enumValueName(error)); -} - -void TestStates::save_load_states() -{ - ThingClass mockDeviceClass = NymeaCore::instance()->thingManager()->findThingClass(mockThingClassId); - - QVERIFY2(mockDeviceClass.getStateType(mockIntStateTypeId).cached(), "Mock int state is not cached (required to be true for this test)"); - QVERIFY2(!mockDeviceClass.getStateType(mockBoolStateTypeId).cached(), "Mock bool state is cached (required to be false for this test)"); - - Thing* device = NymeaCore::instance()->thingManager()->findConfiguredThings(mockThingClassId).first(); - int port = device->paramValue(mockThingHttpportParamTypeId).toInt(); - QNetworkAccessManager nam; - QSignalSpy spy(&nam, SIGNAL(finished(QNetworkReply*))); - - - // First set the state values to something that is *not* the default - int newIntValue = mockDeviceClass.getStateType(mockIntStateTypeId).defaultValue().toInt() + 1; - bool newBoolValue = !mockDeviceClass.getStateType(mockBoolStateTypeId).defaultValue().toBool(); - - QNetworkRequest request(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockIntStateTypeId.toString()).arg(newIntValue))); - QNetworkReply *reply = nam.get(request); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - spy.wait(); - - spy.clear(); - request = QNetworkRequest(QUrl(QString("http://localhost:%1/setstate?%2=%3").arg(port).arg(mockBoolStateTypeId.toString()).arg(newBoolValue))); - reply = nam.get(request); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - spy.wait(); - - // For completeness, verify through JSONRPC that they were actually yet. - QVariantMap params; - params.insert("deviceId", device->id()); - - params["stateTypeId"] = mockIntStateTypeId; - QVariant response = injectAndWait("Devices.GetStateValue", params); - QCOMPARE(response.toMap().value("params").toMap().value("value").toInt(), newIntValue); - - params["stateTypeId"] = mockBoolStateTypeId; - response = injectAndWait("Devices.GetStateValue", params); - QCOMPARE(response.toMap().value("params").toMap().value("value").toBool(), newBoolValue); - - // Restart the server - restartServer(); - - // And check if the cached int state has successfully been restored - params["stateTypeId"] = mockIntStateTypeId; - response = injectAndWait("Devices.GetStateValue", params); - QCOMPARE(response.toMap().value("params").toMap().value("value").toInt(), newIntValue); - - // and that the non-cached bool state is back to its default - params["stateTypeId"] = mockBoolStateTypeId; - response = injectAndWait("Devices.GetStateValue", params); - QCOMPARE(response.toMap().value("params").toMap().value("value").toBool(), mockDeviceClass.getStateType(mockBoolStateTypeId).defaultValue().toBool()); -} - -#include "teststates.moc" -QTEST_MAIN(TestStates) diff --git a/tests/auto/tags/testtags.cpp b/tests/auto/tags/testtags.cpp index f453dfad..af9474e3 100644 --- a/tests/auto/tags/testtags.cpp +++ b/tests/auto/tags/testtags.cpp @@ -83,7 +83,6 @@ QVariantMap TestTags::createRuleTag(const QString &ruleId, const QString &appId, bool TestTags::compareThingTag(const QVariantMap &tag, const QUuid &thingId, const QString &appId, const QString &tagId, const QString &value) { return tag.value("thingId").toUuid() == thingId && - tag.value("deviceId").toUuid() == thingId && // backwards compatibility to < 0.19 adds deviceId along with thingId tag.value("appId").toString() == appId && tag.value("tagId").toString() == tagId && tag.value("value").toString() == value; diff --git a/tests/auto/timemanager/testtimemanager.cpp b/tests/auto/timemanager/testtimemanager.cpp index 66d666ea..92a6c7e6 100644 --- a/tests/auto/timemanager/testtimemanager.cpp +++ b/tests/auto/timemanager/testtimemanager.cpp @@ -141,14 +141,13 @@ private: void TestTimeManager::initTestCase() { - NymeaTestBase::initTestCase(); - QLoggingCategory::setFilterRules("*.debug=false\n" - "Tests.debug=true\n" - "RuleEngine.debug=true\n" -// "RuleEngineDebug.debug=true\n" - "Mock.debug=true\n" - "JsonRpc.debug=true\n" - "TimeManager.debug=true"); + NymeaTestBase::initTestCase("*.debug=false\n" + "Tests.debug=true\n" + "RuleEngine.debug=true\n" +// "RuleEngineDebug.debug=true\n" + "Mock.debug=true\n" + "JsonRpc.debug=true\n" + "TimeManager.debug=true"); } void TestTimeManager::loadSaveTimeDescriptor_data() @@ -2028,7 +2027,7 @@ void TestTimeManager::initTimeManager() { cleanupMockHistory(); removeAllRules(); - enableNotifications({"Rules", "Integrations", "Events"}); + enableNotifications({"Rules", "Integrations"}); NymeaCore::instance()->timeManager()->stopTimer(); qDebug() << NymeaCore::instance()->timeManager()->currentDateTime().toString(); } @@ -2183,14 +2182,14 @@ void TestTimeManager::triggerMockEvent1() if (eventSpy.isEmpty()) { eventSpy.wait(); } - QVariantList eventTriggerVariants = checkNotifications(eventSpy, "Events.EventTriggered"); + QVariantList eventTriggerVariants = checkNotifications(eventSpy, "Integrations.EventTriggered"); QVERIFY2(eventTriggerVariants.count() == 1, "Did not get Events.EventTriggered notification."); QVERIFY2(eventTriggerVariants.first().toMap().value("params").toMap().contains("event"), "Notification Events.EventTriggered does not contain event."); QVariantMap eventMap = eventTriggerVariants.first().toMap().value("params").toMap().value("event").toMap(); - QVERIFY2(eventMap.contains("thingId"), "Events.EventTriggered notification does not contain thingId"); - QVERIFY2(ThingId(eventMap.value("thingId").toString()) == m_mockThingId, "Events.EventTriggered notification does not contain the correct thingId"); - QVERIFY2(eventMap.contains("eventTypeId"), "Events.EventTriggered notification does not contain eventTypeId"); + QVERIFY2(eventMap.contains("thingId"), "Integrations.EventTriggered notification does not contain thingId"); + QVERIFY2(ThingId(eventMap.value("thingId").toString()) == m_mockThingId, "Integrations.EventTriggered notification does not contain the correct thingId"); + QVERIFY2(eventMap.contains("eventTypeId"), "Integrations.EventTriggered notification does not contain eventTypeId"); QVERIFY2(EventTypeId(eventMap.value("eventTypeId").toString()) == mockEvent1EventTypeId, "Events.EventTriggered notification does not contain the correct eventTypeId"); }