From 56a87e9e97ae343f6916b19d3132a1fe991e89d7 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Fri, 31 Aug 2018 19:41:55 +0200 Subject: [PATCH] devices doesn't access the Engine singleton any more This is a not *that* straight forward. For convenience, Devices offers information from the DeviceClasses and used to get that stuff from the engine. In order to solve this I've added a pointer to the DeviceClass in Device. This however, implies that DeviceClasses must be created before Devices and destroyed after them. As the general concept of the system is built in such a way this isn't an issue but it requires some extra throughts when tearing down things. --- libnymea-app-core/devicemanager.cpp | 27 +++++++++++++++++---- libnymea-app-core/devices.cpp | 37 ++++++++++++----------------- libnymea-app-core/devices.h | 2 +- libnymea-common/types/device.cpp | 11 +++++++++ libnymea-common/types/device.h | 14 ++++++++++- 5 files changed, 62 insertions(+), 29 deletions(-) diff --git a/libnymea-app-core/devicemanager.cpp b/libnymea-app-core/devicemanager.cpp index 48d8fb92..afa06356 100644 --- a/libnymea-app-core/devicemanager.cpp +++ b/libnymea-app-core/devicemanager.cpp @@ -107,6 +107,13 @@ void DeviceManager::notificationReceived(const QVariantMap &data) delete dev; return; } + DeviceClass *dc = deviceClasses()->getDeviceClass(dev->deviceClassId()); + if (!dc) { + qWarning() << "Skipping invalid device. Don't have a device class for it"; + delete dev; + return; + } + dev->setDeviceClass(dc); m_devices->addDevice(dev); } else if (notification == "Devices.DeviceRemoved") { QUuid deviceId = data.value("params").toMap().value("deviceId").toUuid(); @@ -221,6 +228,7 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap ¶ms) qWarning() << "Can't find a deviceClass for this device" << device->name(); continue; } + device->setDeviceClass(dc); // set initial state values QVariantList stateVariantList = deviceVariant.toMap().value("states").toList(); @@ -255,12 +263,21 @@ void DeviceManager::addDeviceResponse(const QVariantMap ¶ms) } else if (params.value("params").toMap().keys().contains("device")) { QVariantMap deviceVariant = params.value("params").toMap().value("device").toMap(); Device *device = new Device(); - if (JsonTypes::unpackDevice(deviceVariant, device)) { - qDebug() << "Device added" << device->id().toString(); - m_devices->addDevice(device); - } else { - qWarning() << "Error unpacking device json"; + if (!JsonTypes::unpackDevice(deviceVariant, device)) { + qWarning() << "Couldn't parse json in addDeviceResponse"; + device->deleteLater(); + return; } + DeviceClass *dc = deviceClasses()->getDeviceClass(device->deviceClassId()); + if (!dc) { + qWarning() << "Uh.. We couldn't find a DeviceClass for the Device we just added. Skipping..."; + device->deleteLater(); + return; + } + device->setDeviceClass(dc); + + qDebug() << "Device added" << device->id().toString(); + m_devices->addDevice(device); } emit addDeviceReply(params.value("params").toMap()); } diff --git a/libnymea-app-core/devices.cpp b/libnymea-app-core/devices.cpp index f9079346..d6398282 100644 --- a/libnymea-app-core/devices.cpp +++ b/libnymea-app-core/devices.cpp @@ -75,54 +75,47 @@ QVariant Devices::data(const QModelIndex &index, int role) const case RoleSetupComplete: return device->setupComplete(); case RoleInterfaces: { - DeviceClass *dc = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(device->deviceClassId()); - if (!dc) { - return QVariant(); - } - return dc->interfaces(); + return device->deviceClass()->interfaces(); } case RoleBaseInterface: { - DeviceClass *dc = Engine::instance()->deviceManager()->deviceClasses()->getDeviceClass(device->deviceClassId()); - if (!dc) { - return QVariant(); - } - if (dc->interfaces().contains("gateway")) { + QStringList interfaces = device->deviceClass()->interfaces(); + if (interfaces.contains("gateway")) { return "gateway"; } - if (dc->interfaces().contains("shutter")) { + if (interfaces.contains("shutter")) { return "shutter"; } - if (dc->interfaces().contains("blind")) { + if (interfaces.contains("blind")) { return "blind"; } - if (dc->interfaces().contains("garagegate")) { + if (interfaces.contains("garagegate")) { return "garagegate"; } - if (dc->interfaces().contains("inputtrigger")) { + if (interfaces.contains("inputtrigger")) { return "inputtrigger"; } - if (dc->interfaces().contains("awning")) { + if (interfaces.contains("awning")) { return "awning"; } - if (dc->interfaces().contains("outputtrigger")) { + if (interfaces.contains("outputtrigger")) { return "outputtrigger"; } - if (dc->interfaces().contains("light")) { + if (interfaces.contains("light")) { return "light"; } - if (dc->interfaces().contains("sensor")) { + if (interfaces.contains("sensor")) { return "sensor"; } - if (dc->interfaces().contains("weather")) { + if (interfaces.contains("weather")) { return "weather"; } - if (dc->interfaces().contains("media")) { + if (interfaces.contains("media")) { return "media"; } - if (dc->interfaces().contains("button")) { + if (interfaces.contains("button")) { return "button"; } - if (dc->interfaces().contains("notifications")) { + if (interfaces.contains("notifications")) { return "notifications"; } return "uncategorized"; diff --git a/libnymea-app-core/devices.h b/libnymea-app-core/devices.h index 5d68d42f..1280020b 100644 --- a/libnymea-app-core/devices.h +++ b/libnymea-app-core/devices.h @@ -43,7 +43,7 @@ public: }; Q_ENUM(Roles) - explicit Devices(QObject *parent = 0); + explicit Devices(QObject *parent = nullptr); QList devices(); diff --git a/libnymea-common/types/device.cpp b/libnymea-common/types/device.cpp index 4d85e68e..b6d73868 100644 --- a/libnymea-common/types/device.cpp +++ b/libnymea-common/types/device.cpp @@ -21,6 +21,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "device.h" +#include "deviceclass.h" #include @@ -93,6 +94,16 @@ void Device::setStates(States *states) emit statesChanged(); } +DeviceClass *Device::deviceClass() const +{ + return m_deviceClass; +} + +void Device::setDeviceClass(DeviceClass *deviceClass) +{ + m_deviceClass = deviceClass; +} + bool Device::hasState(const QUuid &stateTypeId) { foreach (State *state, states()->states()) { diff --git a/libnymea-common/types/device.h b/libnymea-common/types/device.h index a5f25a82..d475f7db 100644 --- a/libnymea-common/types/device.h +++ b/libnymea-common/types/device.h @@ -30,6 +30,8 @@ #include "states.h" #include "statesproxy.h" +class DeviceClass; + class Device : public QObject { Q_OBJECT @@ -39,9 +41,10 @@ class Device : public QObject Q_PROPERTY(bool setupComplete READ setupComplete NOTIFY setupCompleteChanged) Q_PROPERTY(Params *params READ params NOTIFY paramsChanged) Q_PROPERTY(States *states READ states NOTIFY statesChanged) + Q_PROPERTY(DeviceClass *deviceClass READ deviceClass CONSTANT) public: - explicit Device(QObject *parent = 0); + explicit Device(QObject *parent = nullptr); QString name() const; void setName(const QString &name); @@ -61,11 +64,18 @@ public: States *states() const; void setStates(States *states); + DeviceClass *deviceClass() const; + Q_INVOKABLE bool hasState(const QUuid &stateTypeId); Q_INVOKABLE QVariant stateValue(const QUuid &stateTypeId); void setStateValue(const QUuid &stateTypeId, const QVariant &value); +private: + void setDeviceClass(DeviceClass *deviceClass); + + friend class DeviceManager; + private: QString m_name; QUuid m_id; @@ -73,6 +83,8 @@ private: bool m_setupComplete; Params *m_params = nullptr; States *m_states = nullptr; + DeviceClass *m_deviceClass = nullptr; + signals: void nameChanged();