Merge PR #347: Change group behavior a bit

This commit is contained in:
Jenkins nymea 2020-03-27 01:05:36 +01:00
commit dd1ee7e352
271 changed files with 1060 additions and 422 deletions

View File

@ -33,6 +33,8 @@
#include "jsonrpc/jsontypes.h"
#include "types/browseritems.h"
#include "types/browseritem.h"
#include "thinggroup.h"
#include "types/interface.h"
#include <QMetaEnum>
DeviceManager::DeviceManager(JsonRpcClient* jsonclient, QObject *parent) :
@ -133,6 +135,7 @@ void DeviceManager::addDevice(const QUuid &deviceClassId, const QString &name, c
void DeviceManager::notificationReceived(const QVariantMap &data)
{
QString notification = data.value("notification").toString();
qDebug() << "*** Notification received:" << notification;
if (notification == "Devices.StateChanged") {
// qDebug() << "Device state changed" << data.value("params");
Device *dev = m_devices->getDevice(data.value("params").toMap().value("deviceId").toUuid());
@ -142,7 +145,7 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
}
dev->setStateValue(data.value("params").toMap().value("stateTypeId").toUuid(), data.value("params").toMap().value("value"));
} else if (notification == "Devices.DeviceAdded") {
Device *dev = JsonTypes::unpackDevice(data.value("params").toMap().value("device").toMap(), m_deviceClasses);
Device *dev = JsonTypes::unpackDevice(this, data.value("params").toMap().value("device").toMap(), m_deviceClasses);
if (!dev) {
qWarning() << "Cannot parse json device:" << data;
return;
@ -158,6 +161,10 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
QUuid deviceId = data.value("params").toMap().value("deviceId").toUuid();
qDebug() << "JsonRpc: Notification: Device removed" << deviceId.toString();
Device *device = m_devices->getDevice(deviceId);
if (!device) {
qWarning() << "Received a DeviceRemoved notification for a device we don't know!";
return;
}
m_devices->removeDevice(device);
device->deleteLater();
} else if (notification == "Devices.DeviceChanged") {
@ -168,7 +175,7 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
qWarning() << "Received a device changed notification for a device we don't know";
return;
}
if (!JsonTypes::unpackDevice(data.value("params").toMap().value("device").toMap(), m_deviceClasses, oldDevice)) {
if (!JsonTypes::unpackDevice(this, data.value("params").toMap().value("device").toMap(), m_deviceClasses, oldDevice)) {
qWarning() << "Error parsing device changed notification";
return;
}
@ -282,7 +289,7 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap &params)
if (params.value("params").toMap().keys().contains("devices")) {
QVariantList deviceList = params.value("params").toMap().value("devices").toList();
foreach (QVariant deviceVariant, deviceList) {
Device *device = JsonTypes::unpackDevice(deviceVariant.toMap(), m_deviceClasses);
Device *device = JsonTypes::unpackDevice(this, deviceVariant.toMap(), m_deviceClasses);
if (!device) {
qWarning() << "Error unpacking device" << deviceVariant.toMap().value("name").toString();
continue;
@ -323,7 +330,7 @@ void DeviceManager::addDeviceResponse(const QVariantMap &params)
qWarning() << "Failed to add the device:" << params.value("params").toMap().value("deviceError").toString();
} else if (params.value("params").toMap().keys().contains("device")) {
QVariantMap deviceVariant = params.value("params").toMap().value("device").toMap();
Device *device = JsonTypes::unpackDevice(deviceVariant, m_deviceClasses);
Device *device = JsonTypes::unpackDevice(this, deviceVariant, m_deviceClasses);
if (!device) {
qWarning() << "Couldn't parse json in addDeviceResponse";
return;
@ -394,6 +401,13 @@ void DeviceManager::savePluginConfig(const QUuid &pluginId)
m_jsonClient->sendCommand("Devices.SetPluginConfiguration", params, this, "setPluginConfigResponse");
}
ThingGroup *DeviceManager::createGroup(Interface *interface, DevicesProxy *things)
{
ThingGroup* group = new ThingGroup(this, interface->createDeviceClass(), things, this);
group->setSetupStatus(Device::DeviceSetupStatusComplete, QString());
return group;
}
void DeviceManager::addDiscoveredDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name, const QVariantList &deviceParams)
{
qDebug() << "JsonRpc: add discovered device " << deviceClassId.toString();

View File

@ -44,6 +44,8 @@
class BrowserItem;
class BrowserItems;
class EventHandler;
class ThingGroup;
class Interface;
class DeviceManager : public JsonHandler
{
@ -120,6 +122,8 @@ private:
public slots:
void savePluginConfig(const QUuid &pluginId);
ThingGroup* createGroup(Interface *interface, DevicesProxy *things);
signals:
void pairDeviceReply(const QVariantMap &params);
void confirmPairingReply(const QVariantMap &params);

View File

@ -76,6 +76,9 @@ void DevicesProxy::setParentProxy(DevicesProxy *parentProxy)
m_parentProxy = parentProxy;
setSourceModel(parentProxy);
if (!m_engine) {
return;
}
setSortRole(Devices::RoleName);
sort(0);
connect(m_parentProxy, SIGNAL(countChanged()), this, SIGNAL(countChanged()));

View File

@ -31,6 +31,7 @@
#include "interfacesmodel.h"
#include "engine.h"
#include "devicesproxy.h"
InterfacesModel::InterfacesModel(QObject *parent):
QAbstractListModel(parent)
@ -60,20 +61,49 @@ QHash<int, QByteArray> InterfacesModel::roleNames() const
return roles;
}
DeviceManager *InterfacesModel::deviceManager() const
Engine *InterfacesModel::engine() const
{
return m_deviceManager;
return m_engine;
}
void InterfacesModel::setDeviceManager(DeviceManager *deviceManager)
void InterfacesModel::setEngine(Engine *engine)
{
if (m_deviceManager != deviceManager) {
m_deviceManager = deviceManager;
emit deviceManagerChanged();
connect(m_deviceManager->devices(), &Devices::countChanged, this, [this]() {
if (m_engine != engine) {
static QMetaObject::Connection countChangedConnection;
if (m_engine) {
disconnect(countChangedConnection);
}
m_engine = engine;
emit engineChanged();
countChangedConnection = connect(engine->deviceManager()->deviceClasses(), &DeviceClasses::countChanged, this, [this]() {
syncInterfaces();
});
connect(m_deviceManager->deviceClasses(), &DeviceClasses::countChanged, this, [this]() {
syncInterfaces();
}
}
DevicesProxy *InterfacesModel::devices() const
{
return m_devicesProxy;
}
void InterfacesModel::setDevices(DevicesProxy *devices)
{
if (m_devicesProxy != devices) {
static QMetaObject::Connection countChangedConnection;
if (m_devicesProxy) {
disconnect(countChangedConnection);
}
m_devicesProxy = devices;
emit devicesChanged();
countChangedConnection = connect(devices, &DevicesProxy::countChanged, this, [this]() {
syncInterfaces();
});
syncInterfaces();
@ -95,20 +125,6 @@ void InterfacesModel::setShownInterfaces(const QStringList &shownInterfaces)
}
}
bool InterfacesModel::onlyConfiguredDevices() const
{
return m_onlyConfiguredDevices;
}
void InterfacesModel::setOnlyConfiguredDevices(bool onlyConfigured)
{
if (m_onlyConfiguredDevices != onlyConfigured) {
m_onlyConfiguredDevices = onlyConfigured;
emit onlyConfiguredDevicesChanged();
syncInterfaces();
}
}
bool InterfacesModel::showUncategorized() const
{
return m_showUncategorized;
@ -133,17 +149,17 @@ QString InterfacesModel::get(int index) const
void InterfacesModel::syncInterfaces()
{
if (!m_deviceManager) {
if (!m_engine) {
return;
}
QList<DeviceClass*> deviceClasses;
if (m_onlyConfiguredDevices) {
for (int i = 0; i < m_deviceManager->devices()->rowCount(); i++) {
deviceClasses << m_deviceManager->deviceClasses()->getDeviceClass(m_deviceManager->devices()->get(i)->deviceClassId());
if (m_devicesProxy) {
for (int i = 0; i < m_devicesProxy->rowCount(); i++) {
deviceClasses << m_engine->deviceManager()->deviceClasses()->getDeviceClass(m_devicesProxy->get(i)->deviceClassId());
}
} else {
for (int i = 0; i < m_deviceManager->deviceClasses()->rowCount(); i++) {
deviceClasses << m_deviceManager->deviceClasses()->get(i);
for (int i = 0; i < m_engine->deviceManager()->deviceClasses()->rowCount(); i++) {
deviceClasses << m_engine->deviceManager()->deviceClasses()->get(i);
}
}

View File

@ -36,16 +36,20 @@
#include "devices.h"
class DeviceManager;
class Engine;
class DevicesProxy;
class InterfacesModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(DeviceManager* deviceManager READ deviceManager WRITE setDeviceManager NOTIFY deviceManagerChanged)
Q_PROPERTY(QStringList shownInterfaces READ shownInterfaces WRITE setShownInterfaces NOTIFY shownInterfacesChanged)
Q_PROPERTY(bool onlyConfiguredDevices READ onlyConfiguredDevices WRITE setOnlyConfiguredDevices NOTIFY onlyConfiguredDevicesChanged)
// Required
Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged)
// Optional filters
Q_PROPERTY(DevicesProxy* devices READ devices WRITE setDevices NOTIFY devicesChanged)
Q_PROPERTY(QStringList shownInterfaces READ shownInterfaces WRITE setShownInterfaces NOTIFY shownInterfacesChanged)
Q_PROPERTY(bool showUncategorized READ showUncategorized WRITE setShowUncategorized NOTIFY showUncategorizedChanged)
public:
@ -60,8 +64,11 @@ public:
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
DeviceManager* deviceManager() const;
void setDeviceManager(DeviceManager *deviceManager);
Engine* engine() const;
void setEngine(Engine *engine);
DevicesProxy* devices() const;
void setDevices(DevicesProxy *devices);
QStringList shownInterfaces() const;
void setShownInterfaces(const QStringList &shownInterfaces);
@ -76,7 +83,8 @@ public:
signals:
void countChanged();
void deviceManagerChanged();
void engineChanged();
void devicesChanged();
void shownInterfacesChanged();
bool onlyConfiguredDevicesChanged();
void showUncategorizedChanged();
@ -86,11 +94,11 @@ private slots:
void rowsChanged(const QModelIndex &index, int first, int last);
private:
DeviceManager *m_deviceManager = nullptr;
Engine *m_engine = nullptr;
QStringList m_interfaces;
DevicesProxy *m_devicesProxy = nullptr;
QStringList m_shownInterfaces;
bool m_onlyConfiguredDevices = true;
bool m_showUncategorized = false;
};

View File

@ -222,7 +222,7 @@ ActionType *JsonTypes::unpackActionType(const QVariantMap &actionTypeMap, QObjec
return actionType;
}
Device* JsonTypes::unpackDevice(const QVariantMap &deviceMap, DeviceClasses *deviceClasses, Device *oldDevice)
Device* JsonTypes::unpackDevice(DeviceManager *deviceManager, const QVariantMap &deviceMap, DeviceClasses *deviceClasses, Device *oldDevice)
{
QUuid deviceClassId = deviceMap.value("deviceClassId").toUuid();
DeviceClass *deviceClass = deviceClasses->getDeviceClass(deviceClassId);
@ -236,15 +236,23 @@ Device* JsonTypes::unpackDevice(const QVariantMap &deviceMap, DeviceClasses *dev
if (oldDevice) {
device = oldDevice;
} else {
device = new Device(deviceClass, parentDeviceId);
device = new Device(deviceManager, deviceClass, parentDeviceId);
}
device->setName(deviceMap.value("name").toString());
device->setId(deviceMap.value("id").toUuid());
// As of JSONRPC 4.2 setupComplete is deprecated and setupStatus is new
if (deviceMap.contains("setupStatus")) {
QMetaEnum setupStatusEnum = QMetaEnum::fromType<Device::DeviceSetupStatus>();
device->setSetupStatus(static_cast<Device::DeviceSetupStatus>(setupStatusEnum.keyToValue(deviceMap.value("setupStatus").toByteArray().data())),
deviceMap.value("setupDisplayMessage").toString());
QString setupStatus = deviceMap.value("setupStatus").toString();
QString setupDisplayMessage = deviceMap.value("setupDisplayMessage").toString();
if (setupStatus == "DeviceSetupStatusNone" || setupStatus == "ThingSetupStatusNone") {
device->setSetupStatus(Device::DeviceSetupStatusNone, setupDisplayMessage);
} else if (setupStatus == "DeviceSetupStatusInProgress" || setupStatus == "ThingSetupStatusInProgress") {
device->setSetupStatus(Device::DeviceSetupStatusInProgress, setupDisplayMessage);
} else if (setupStatus == "DeviceSetupStatusComplete" || setupStatus == "ThingSetupStatusComplete") {
device->setSetupStatus(Device::DeviceSetupStatusComplete, setupDisplayMessage);
} else if (setupStatus == "DeviceSetupStatusFailed" || setupStatus == "ThingSetupStatusFailed") {
device->setSetupStatus(Device::DeviceSetupStatusFailed, setupDisplayMessage);
}
} else {
device->setSetupStatus(deviceMap.value("setupComplete").toBool() ? Device::DeviceSetupStatusComplete : Device::DeviceSetupStatusNone, QString());
}

View File

@ -47,6 +47,7 @@ class EventType;
class ActionType;
class ParamType;
class DeviceManager;
class Device;
class DeviceClasses;
class Param;
@ -73,7 +74,7 @@ public:
static StateType *unpackStateType(const QVariantMap &stateTypeMap, QObject *parent);
static EventType *unpackEventType(const QVariantMap &eventTypeMap, QObject *parent);
static ActionType *unpackActionType(const QVariantMap &actionTypeMap, QObject *parent);
static Device *unpackDevice(const QVariantMap &deviceMap, DeviceClasses *deviceClasses, Device *oldDevice = nullptr);
static Device *unpackDevice(DeviceManager *deviceManager, const QVariantMap &deviceMap, DeviceClasses *deviceClasses, Device *oldDevice = nullptr);
static QVariantMap packRule(Rule* rule);
static QVariantList packRuleActions(RuleActions* ruleActions);

View File

@ -109,6 +109,7 @@
#include "types/tokeninfos.h"
#include "types/tokeninfo.h"
#include "types/userinfo.h"
#include "thinggroup.h"
#include <QtQml/qqml.h>
@ -211,6 +212,8 @@ void registerQmlTypes() {
qmlRegisterSingletonType<Interfaces>(uri, 1, 0, "Interfaces", interfacesModel_provider);
qmlRegisterType<InterfacesProxy>(uri, 1, 0, "InterfacesProxy");
qmlRegisterUncreatableType<ThingGroup>(uri, 1, 0, "ThingGroup", "Uncreatable");
qmlRegisterUncreatableType<Plugin>(uri, 1, 0, "Plugin", "Can't create this in QML. Get it from the Plugins.");
qmlRegisterUncreatableType<Plugins>(uri, 1, 0, "Plugins", "Can't create this in QML. Get it from the DeviceManager.");
qmlRegisterType<PluginsProxy>(uri, 1, 0, "PluginsProxy");

View File

@ -1,4 +1,4 @@
TARGET = nymea-app-core
TARGET = nymea-app
TEMPLATE = lib
CONFIG += staticlib
@ -22,12 +22,70 @@ QT += network websockets bluetooth charts quick
LIBS += -lssl -lcrypto
INCLUDEPATH += $$top_srcdir/libnymea-common \
$$top_srcdir/QtZeroConf
INCLUDEPATH += $$top_srcdir/QtZeroConf
SOURCES += \
configuration/networkmanager.cpp \
engine.cpp \
types/browseritem.cpp \
types/browseritems.cpp \
types/networkdevice.cpp \
types/networkdevices.cpp \
types/package.cpp \
types/packages.cpp \
types/repositories.cpp \
types/repository.cpp \
types/script.cpp \
types/scripts.cpp \
types/types.cpp \
types/vendor.cpp \
types/vendors.cpp \
types/deviceclass.cpp \
types/device.cpp \
types/param.cpp \
types/params.cpp \
types/paramtype.cpp \
types/paramtypes.cpp \
types/statetype.cpp \
types/statetypes.cpp \
types/eventtype.cpp \
types/eventtypes.cpp \
types/actiontype.cpp \
types/actiontypes.cpp \
types/state.cpp \
types/states.cpp \
types/statesproxy.cpp \
types/plugin.cpp \
types/plugins.cpp \
types/rules.cpp \
types/rule.cpp \
types/eventdescriptor.cpp \
types/eventdescriptors.cpp \
types/ruleaction.cpp \
types/ruleactions.cpp \
types/ruleactionparams.cpp \
types/ruleactionparam.cpp \
types/logentry.cpp \
types/stateevaluators.cpp \
types/stateevaluator.cpp \
types/statedescriptor.cpp \
types/paramdescriptor.cpp \
types/paramdescriptors.cpp \
types/interface.cpp \
types/interfaces.cpp \
types/timedescriptor.cpp \
types/timeeventitem.cpp \
types/calendaritem.cpp \
types/timeeventitems.cpp \
types/calendaritems.cpp \
types/repeatingoption.cpp \
types/tag.cpp \
types/tags.cpp \
types/wirelessaccesspoint.cpp \
types/wirelessaccesspoints.cpp \
types/tokeninfo.cpp \
types/tokeninfos.cpp \
types/userinfo.cpp \
connection/nymeahost.cpp \
connection/nymeahosts.cpp \
connection/nymeaconnection.cpp \
@ -91,11 +149,71 @@ SOURCES += \
configuration/mqttpolicies.cpp \
models/devicemodel.cpp \
system/systemcontroller.cpp \
thinggroup.cpp \
HEADERS += \
configuration/networkmanager.h \
engine.h \
types/browseritem.h \
types/browseritems.h \
types/networkdevice.h \
types/networkdevices.h \
types/package.h \
types/packages.h \
types/repositories.h \
types/repository.h \
types/script.h \
types/scripts.h \
types/types.h \
types/vendor.h \
types/vendors.h \
types/deviceclass.h \
types/device.h \
types/param.h \
types/params.h \
types/paramtype.h \
types/paramtypes.h \
types/statetype.h \
types/statetypes.h \
types/eventtype.h \
types/eventtypes.h \
types/actiontype.h \
types/actiontypes.h \
types/state.h \
types/states.h \
types/statesproxy.h \
types/plugin.h \
types/plugins.h \
types/rules.h \
types/rule.h \
types/eventdescriptor.h \
types/eventdescriptors.h \
types/ruleaction.h \
types/ruleactions.h \
types/ruleactionparams.h \
types/ruleactionparam.h \
types/logentry.h \
types/stateevaluators.h \
types/stateevaluator.h \
types/statedescriptor.h \
types/paramdescriptor.h \
types/paramdescriptors.h \
types/interface.h \
types/interfaces.h \
types/timedescriptor.h \
types/timeeventitem.h \
types/calendaritem.h \
types/timeeventitems.h \
types/calendaritems.h \
types/repeatingoption.h \
types/tag.h \
types/tags.h \
types/wirelessaccesspoint.h \
types/wirelessaccesspoints.h \
types/tokeninfo.h \
types/tokeninfos.h \
types/userinfo.h \
connection/nymeahost.h \
connection/nymeahosts.h \
connection/nymeaconnection.h \
@ -160,6 +278,7 @@ HEADERS += \
configuration/mqttpolicies.h \
models/devicemodel.h \
system/systemcontroller.h \
thinggroup.h \
ubports: {
DEFINES += UBPORTS

View File

@ -160,3 +160,15 @@ Interface *InterfacesProxy::get(int index) const
{
return m_interfaces->get(mapToSource(this->index(index, 0)).row());
}
Interface *InterfacesProxy::getInterface(const QString &name) const
{
qDebug() << "Getting iface" << name;
for (int i = 0; i < rowCount(); i++) {
if (get(i)->name() == name) {
qDebug() << "checking" << get(i)->name();
return get(i);
}
}
return nullptr;
}

View File

@ -74,6 +74,7 @@ public:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
Q_INVOKABLE Interface* get(int index) const;
Q_INVOKABLE Interface* getInterface(const QString &name) const;
signals:
void shownInterfacesChanged();

View File

@ -406,6 +406,7 @@ bool LogsModelNg::canFetchMore(const QModelIndex &parent) const
void LogsModelNg::newLogEntryReceived(const QVariantMap &data)
{
qDebug() << "***** model NG" << data << m_live;
if (!m_live) {
return;
}
@ -421,6 +422,7 @@ void LogsModelNg::newLogEntryReceived(const QVariantMap &data)
return;
}
qDebug() << "Adding entry!!!!!!";
beginInsertRows(QModelIndex(), 0, 0);
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();

Some files were not shown because too many files have changed in this diff Show More