/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* 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 "devicediscovery.h"
#include "engine.h"
DeviceDiscovery::DeviceDiscovery(QObject *parent) :
QAbstractListModel(parent)
{
}
int DeviceDiscovery::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_foundDevices.count();
}
QVariant DeviceDiscovery::data(const QModelIndex &index, int role) const
{
switch (role) {
case RoleId:
return m_foundDevices.at(index.row())->id();
case RoleName:
return m_foundDevices.at(index.row())->name();
case RoleDescription:
return m_foundDevices.at(index.row())->description();
case RoleDeviceId:
return m_foundDevices.at(index.row())->deviceId();
}
return QVariant();
}
QHash DeviceDiscovery::roleNames() const
{
QHash roles;
roles.insert(RoleId, "id");
roles.insert(RoleDeviceId, "deviceId");
roles.insert(RoleName, "name");
roles.insert(RoleDescription, "description");
return roles;
}
void DeviceDiscovery::discoverDevices(const QUuid &deviceClassId, const QVariantList &discoveryParams)
{
if (m_busy) {
qWarning() << "Busy... not restarting discovery";
return;
}
beginResetModel();
m_foundDevices.clear();
endResetModel();
emit countChanged();
if (!m_engine) {
qWarning() << "Cannot discover devices. No Engine set";
return;
}
if (!m_engine->jsonRpcClient()->connected()) {
qWarning() << "Cannot discover devices. Not connected.";
return;
}
QVariantMap params;
params.insert("deviceClassId", deviceClassId.toString());
if (!discoveryParams.isEmpty()) {
params.insert("discoveryParams", discoveryParams);
}
m_engine->jsonRpcClient()->sendCommand("Devices.GetDiscoveredDevices", params, this, "discoverDevicesResponse");
m_busy = true;
m_displayMessage.clear();
emit busyChanged();
}
DeviceDescriptor *DeviceDiscovery::get(int index) const
{
if (index < 0 || index >= m_foundDevices.count()) {
return nullptr;
}
return m_foundDevices.at(index);
}
Engine *DeviceDiscovery::engine() const
{
return m_engine;
}
void DeviceDiscovery::setEngine(Engine *engine)
{
if (m_engine != engine) {
m_engine = engine;
emit engineChanged();
}
}
bool DeviceDiscovery::busy() const
{
return m_busy;
}
QString DeviceDiscovery::displayMessage() const
{
return m_displayMessage;
}
void DeviceDiscovery::discoverDevicesResponse(int /*commandId*/, const QVariantMap ¶ms)
{
// qDebug() << "response received" << params;
QVariantList descriptors = params.value("deviceDescriptors").toList();
foreach (const QVariant &descriptorVariant, descriptors) {
qDebug() << "Found device. Descriptor:" << descriptorVariant;
if (!contains(descriptorVariant.toMap().value("id").toUuid())) {
beginInsertRows(QModelIndex(), m_foundDevices.count(), m_foundDevices.count());
DeviceDescriptor *descriptor = new DeviceDescriptor(descriptorVariant.toMap().value("id").toUuid(),
descriptorVariant.toMap().value("deviceId").toString(),
descriptorVariant.toMap().value("title").toString(),
descriptorVariant.toMap().value("description").toString());
foreach (const QVariant ¶mVariant, descriptorVariant.toMap().value("deviceParams").toList()) {
qDebug() << "Adding param:" << paramVariant.toMap().value("paramTypeId").toString() << paramVariant.toMap().value("value");
Param* p = new Param(paramVariant.toMap().value("paramTypeId").toString(), paramVariant.toMap().value("value"));
descriptor->params()->addParam(p);
}
m_foundDevices.append(descriptor);
endInsertRows();
emit countChanged();
}
}
m_displayMessage = params.value("displayMessage").toString();
m_busy = false;
emit busyChanged();
}
bool DeviceDiscovery::contains(const QUuid &deviceDescriptorId) const
{
foreach (DeviceDescriptor *descriptor, m_foundDevices) {
if (descriptor->id() == deviceDescriptorId) {
return true;
}
}
return false;
}
DeviceDescriptor::DeviceDescriptor(const QUuid &id, const QUuid &deviceId, const QString &name, const QString &description, QObject *parent):
QObject(parent),
m_id(id),
m_deviceId(deviceId),
m_name(name),
m_description(description),
m_params(new Params(this))
{
}
QUuid DeviceDescriptor::id() const
{
return m_id;
}
QUuid DeviceDescriptor::deviceId() const
{
return m_deviceId;
}
QString DeviceDescriptor::name() const
{
return m_name;
}
QString DeviceDescriptor::description() const
{
return m_description;
}
Params* DeviceDescriptor::params() const
{
return m_params;
}
DeviceDiscoveryProxy::DeviceDiscoveryProxy(QObject *parent):
QSortFilterProxyModel (parent)
{
}
DeviceDiscovery *DeviceDiscoveryProxy::deviceDiscovery() const
{
return m_deviceDiscovery;
}
void DeviceDiscoveryProxy::setDeviceDiscovery(DeviceDiscovery *deviceDiscovery)
{
if (m_deviceDiscovery != deviceDiscovery) {
m_deviceDiscovery = deviceDiscovery;
setSourceModel(deviceDiscovery);
emit deviceDiscoveryChanged();
emit countChanged();
connect(m_deviceDiscovery, &DeviceDiscovery::countChanged, this, &DeviceDiscoveryProxy::countChanged);
invalidateFilter();
}
}
bool DeviceDiscoveryProxy::showAlreadyAdded() const
{
return m_showAlreadyAdded;
}
void DeviceDiscoveryProxy::setShowAlreadyAdded(bool showAlreadyAdded)
{
if (m_showAlreadyAdded != showAlreadyAdded) {
m_showAlreadyAdded = showAlreadyAdded;
emit showAlreadyAddedChanged();
invalidateFilter();
emit countChanged();
}
}
bool DeviceDiscoveryProxy::showNew() const
{
return m_showNew;
}
void DeviceDiscoveryProxy::setShowNew(bool showNew)
{
if (m_showNew != showNew) {
m_showNew = showNew;
emit showNewChanged();
invalidateFilter();
emit countChanged();
}
}
QUuid DeviceDiscoveryProxy::filterDeviceId() const
{
return m_filterDeviceId;
}
void DeviceDiscoveryProxy::setFilterDeviceId(const QUuid &filterDeviceId)
{
if (m_filterDeviceId != filterDeviceId) {
m_filterDeviceId = filterDeviceId;
emit filterDeviceIdChanged();
invalidateFilter();
emit countChanged();
}
}
DeviceDescriptor *DeviceDiscoveryProxy::get(int index) const
{
return m_deviceDiscovery->get(mapToSource(this->index(index, 0)).row());
}
bool DeviceDiscoveryProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
Q_UNUSED(sourceParent)
DeviceDescriptor* dev = m_deviceDiscovery->get(sourceRow);
if (!m_showAlreadyAdded && !dev->deviceId().isNull()) {
return false;
}
if (!m_showNew && dev->deviceId().isNull()) {
return false;
}
if (!m_filterDeviceId.isNull() && dev->deviceId() != m_filterDeviceId) {
return false;
}
return true;
}