296 lines
8.4 KiB
C++
296 lines
8.4 KiB
C++
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
*
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*
|
|
* 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 "thingdiscovery.h"
|
|
|
|
#include "engine.h"
|
|
|
|
ThingDiscovery::ThingDiscovery(QObject *parent) :
|
|
QAbstractListModel(parent)
|
|
{
|
|
}
|
|
|
|
int ThingDiscovery::rowCount(const QModelIndex &parent) const
|
|
{
|
|
Q_UNUSED(parent)
|
|
return m_foundDevices.count();
|
|
}
|
|
|
|
QVariant ThingDiscovery::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())->thingId();
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
QHash<int, QByteArray> ThingDiscovery::roleNames() const
|
|
{
|
|
QHash<int, QByteArray> roles;
|
|
roles.insert(RoleId, "id");
|
|
roles.insert(RoleDeviceId, "deviceId");
|
|
roles.insert(RoleName, "name");
|
|
roles.insert(RoleDescription, "description");
|
|
return roles;
|
|
}
|
|
|
|
void ThingDiscovery::discoverThings(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, "discoverThingsResponse");
|
|
m_busy = true;
|
|
m_displayMessage.clear();
|
|
emit busyChanged();
|
|
}
|
|
|
|
ThingDescriptor *ThingDiscovery::get(int index) const
|
|
{
|
|
if (index < 0 || index >= m_foundDevices.count()) {
|
|
return nullptr;
|
|
}
|
|
return m_foundDevices.at(index);
|
|
}
|
|
|
|
Engine *ThingDiscovery::engine() const
|
|
{
|
|
return m_engine;
|
|
}
|
|
|
|
void ThingDiscovery::setEngine(Engine *engine)
|
|
{
|
|
if (m_engine != engine) {
|
|
m_engine = engine;
|
|
emit engineChanged();
|
|
}
|
|
}
|
|
|
|
bool ThingDiscovery::busy() const
|
|
{
|
|
return m_busy;
|
|
}
|
|
|
|
QString ThingDiscovery::displayMessage() const
|
|
{
|
|
return m_displayMessage;
|
|
}
|
|
|
|
void ThingDiscovery::discoverThingsResponse(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());
|
|
ThingDescriptor *descriptor = new ThingDescriptor(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 ThingDiscovery::contains(const QUuid &deviceDescriptorId) const
|
|
{
|
|
foreach (ThingDescriptor *descriptor, m_foundDevices) {
|
|
if (descriptor->id() == deviceDescriptorId) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ThingDescriptor::ThingDescriptor(const QUuid &id, const QUuid &thingId, const QString &name, const QString &description, QObject *parent):
|
|
QObject(parent),
|
|
m_id(id),
|
|
m_thingId(thingId),
|
|
m_name(name),
|
|
m_description(description),
|
|
m_params(new Params(this))
|
|
{
|
|
|
|
}
|
|
|
|
QUuid ThingDescriptor::id() const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
QUuid ThingDescriptor::thingId() const
|
|
{
|
|
return m_thingId;
|
|
}
|
|
|
|
QString ThingDescriptor::name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
QString ThingDescriptor::description() const
|
|
{
|
|
return m_description;
|
|
}
|
|
|
|
Params* ThingDescriptor::params() const
|
|
{
|
|
return m_params;
|
|
}
|
|
|
|
ThingDiscoveryProxy::ThingDiscoveryProxy(QObject *parent):
|
|
QSortFilterProxyModel (parent)
|
|
{
|
|
|
|
}
|
|
|
|
ThingDiscovery *ThingDiscoveryProxy::thingDiscovery() const
|
|
{
|
|
return m_thingDiscovery;
|
|
}
|
|
|
|
void ThingDiscoveryProxy::setThingDiscovery(ThingDiscovery *thingDiscovery)
|
|
{
|
|
if (m_thingDiscovery != thingDiscovery) {
|
|
m_thingDiscovery = thingDiscovery;
|
|
setSourceModel(thingDiscovery);
|
|
emit thingDiscoveryChanged();
|
|
emit countChanged();
|
|
connect(m_thingDiscovery, &ThingDiscovery::countChanged, this, &ThingDiscoveryProxy::countChanged);
|
|
invalidateFilter();
|
|
}
|
|
}
|
|
|
|
bool ThingDiscoveryProxy::showAlreadyAdded() const
|
|
{
|
|
return m_showAlreadyAdded;
|
|
}
|
|
|
|
void ThingDiscoveryProxy::setShowAlreadyAdded(bool showAlreadyAdded)
|
|
{
|
|
if (m_showAlreadyAdded != showAlreadyAdded) {
|
|
m_showAlreadyAdded = showAlreadyAdded;
|
|
emit showAlreadyAddedChanged();
|
|
invalidateFilter();
|
|
emit countChanged();
|
|
}
|
|
}
|
|
|
|
bool ThingDiscoveryProxy::showNew() const
|
|
{
|
|
return m_showNew;
|
|
}
|
|
|
|
void ThingDiscoveryProxy::setShowNew(bool showNew)
|
|
{
|
|
if (m_showNew != showNew) {
|
|
m_showNew = showNew;
|
|
emit showNewChanged();
|
|
invalidateFilter();
|
|
emit countChanged();
|
|
}
|
|
}
|
|
|
|
QUuid ThingDiscoveryProxy::filterThingId() const
|
|
{
|
|
return m_filterThingId;
|
|
}
|
|
|
|
void ThingDiscoveryProxy::setFilterThingId(const QUuid &filterDeviceId)
|
|
{
|
|
if (m_filterThingId != filterDeviceId) {
|
|
m_filterThingId = filterDeviceId;
|
|
emit filterThingIdChanged();
|
|
invalidateFilter();
|
|
emit countChanged();
|
|
}
|
|
}
|
|
|
|
ThingDescriptor *ThingDiscoveryProxy::get(int index) const
|
|
{
|
|
return m_thingDiscovery->get(mapToSource(this->index(index, 0)).row());
|
|
}
|
|
|
|
bool ThingDiscoveryProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
|
{
|
|
Q_UNUSED(sourceParent)
|
|
ThingDescriptor* dev = m_thingDiscovery->get(sourceRow);
|
|
if (!m_showAlreadyAdded && !dev->thingId().isNull()) {
|
|
return false;
|
|
}
|
|
if (!m_showNew && dev->thingId().isNull()) {
|
|
return false;
|
|
}
|
|
if (!m_filterThingId.isNull() && dev->thingId() != m_filterThingId) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|