also allow reconfiguring of devices that require pairing

This commit is contained in:
Michael Zanetti 2019-01-22 23:39:23 +01:00
parent 03745e8d9f
commit 601171daf8
8 changed files with 194 additions and 15 deletions

View File

@ -22,6 +22,8 @@ QVariant DeviceDiscovery::data(const QModelIndex &index, int role) const
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();
@ -31,6 +33,7 @@ QHash<int, QByteArray> DeviceDiscovery::roleNames() const
{
QHash<int, QByteArray> roles;
roles.insert(RoleId, "id");
roles.insert(RoleDeviceId, "deviceId");
roles.insert(RoleName, "name");
roles.insert(RoleDescription, "description");
return roles;
@ -104,6 +107,7 @@ void DeviceDiscovery::discoverDevicesResponse(const QVariantMap &params)
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 &paramVariant, descriptorVariant.toMap().value("deviceParams").toList()) {
@ -128,9 +132,10 @@ bool DeviceDiscovery::contains(const QUuid &deviceDescriptorId) const
return false;
}
DeviceDescriptor::DeviceDescriptor(const QUuid &id, const QString &name, const QString &description, QObject *parent):
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))
@ -143,6 +148,11 @@ QUuid DeviceDescriptor::id() const
return m_id;
}
QUuid DeviceDescriptor::deviceId() const
{
return m_deviceId;
}
QString DeviceDescriptor::name() const
{
return m_name;
@ -157,3 +167,92 @@ 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;
}

View File

@ -9,19 +9,22 @@
class DeviceDescriptor: public QObject {
Q_OBJECT
Q_PROPERTY(QUuid id READ id CONSTANT)
Q_PROPERTY(QUuid deviceId READ deviceId CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT)
Q_PROPERTY(Params* params READ params CONSTANT)
public:
DeviceDescriptor(const QUuid &id, const QString &name, const QString &description, QObject *parent = nullptr);
DeviceDescriptor(const QUuid &id, const QUuid &deviceId, const QString &name, const QString &description, QObject *parent = nullptr);
QUuid id() const;
QUuid deviceId() const;
QString name() const;
QString description() const;
Params* params() const;
private:
QUuid m_id;
QUuid m_deviceId;
QString m_name;
QString m_description;
Params *m_params = nullptr;
@ -36,6 +39,7 @@ class DeviceDiscovery : public QAbstractListModel
public:
enum Roles {
RoleId,
RoleDeviceId,
RoleName,
RoleDescription
};
@ -72,4 +76,47 @@ private:
QList<DeviceDescriptor*> m_foundDevices;
};
class DeviceDiscoveryProxy: public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(DeviceDiscovery* deviceDiscovery READ deviceDiscovery WRITE setDeviceDiscovery NOTIFY deviceDiscoveryChanged)
Q_PROPERTY(bool showAlreadyAdded READ showAlreadyAdded WRITE setShowAlreadyAdded NOTIFY showAlreadyAddedChanged)
Q_PROPERTY(bool showNew READ showNew WRITE setShowNew NOTIFY showNewChanged)
Q_PROPERTY(QUuid filterDeviceId READ filterDeviceId WRITE setFilterDeviceId NOTIFY filterDeviceIdChanged)
public:
DeviceDiscoveryProxy(QObject *parent = nullptr);
DeviceDiscovery* deviceDiscovery() const;
void setDeviceDiscovery(DeviceDiscovery* deviceDiscovery);
bool showAlreadyAdded() const;
void setShowAlreadyAdded(bool showAlreadyAdded);
bool showNew() const;
void setShowNew(bool showNew);
QUuid filterDeviceId() const;
void setFilterDeviceId(const QUuid &filterDeviceId);
Q_INVOKABLE DeviceDescriptor* get(int index) const;
signals:
void countChanged();
void deviceDiscoveryChanged();
void showAlreadyAddedChanged();
void showNewChanged();
void filterDeviceIdChanged();
protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
private:
DeviceDiscovery* m_deviceDiscovery = nullptr;
bool m_showAlreadyAdded = false;
bool m_showNew = true;
QUuid m_filterDeviceId;
};
#endif // DEVICEDISCOVERY_H

View File

@ -114,6 +114,7 @@ void registerQmlTypes() {
qmlRegisterUncreatableType<DeviceClasses>(uri, 1, 0, "DeviceClasses", "Can't create this in QML. Get it from the DeviceManager.");
qmlRegisterType<DeviceClassesProxy>(uri, 1, 0, "DeviceClassesProxy");
qmlRegisterType<DeviceDiscovery>(uri, 1, 0, "DeviceDiscovery");
qmlRegisterType<DeviceDiscoveryProxy>(uri, 1, 0, "DeviceDiscoveryProxy");
qmlRegisterUncreatableType<DeviceDescriptor>(uri, 1, 0, "DeviceDescriptor", "Get it from DeviceDiscovery");
qmlRegisterType<DeviceModel>(uri, 1, 0, "DeviceModel");

View File

@ -26,7 +26,7 @@
VendorsProxy::VendorsProxy(QObject *parent) : QSortFilterProxyModel(parent)
{
setSortRole(Vendors::RoleDisplayName);
}
Vendors *VendorsProxy::vendors()
@ -40,10 +40,16 @@ void VendorsProxy::setVendors(Vendors *vendors)
m_vendors = vendors;
setSourceModel(vendors);
emit vendorsChanged();
connect(m_vendors, &Vendors::countChanged, this, &VendorsProxy::countChanged);
sort(0);
}
}
Vendor *VendorsProxy::get(int index) const
{
return m_vendors->get(mapToSource(this->index(index, 0)).row());
}
bool VendorsProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
QVariant leftName = sourceModel()->data(left);

View File

@ -32,6 +32,7 @@ class VendorsProxy : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(Vendors *vendors READ vendors WRITE setVendors NOTIFY vendorsChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
public:
explicit VendorsProxy(QObject *parent = nullptr);
@ -39,8 +40,11 @@ public:
Vendors *vendors();
void setVendors(Vendors *vendors);
Q_INVOKABLE Vendor* get(int index) const;
signals:
void vendorsChanged();
void countChanged();
private:
Vendors *m_vendors;

View File

@ -97,7 +97,7 @@ Page {
imageSource: "images/starred.svg"
buttonVisible: engine.deviceManager.devices.count === 0
buttonText: qsTr("Add a thing")
onButtonClicked: pageStack.push(Qt.resolvedUrl("NewDeviceWizard.qml"))
onButtonClicked: pageStack.push(Qt.resolvedUrl("thingconfiguration/NewThingPage.qml"))
}
}
@ -124,7 +124,7 @@ Page {
text: qsTr("There are no things set up yet.") + "\n" + qsTr("In order for your %1 box to be useful, go ahead and add some things.").arg(app.systemName)
imageSource: "qrc:/styles/%1/logo.svg".arg(styleController.currentStyle)
buttonText: qsTr("Add a thing")
onButtonClicked: pageStack.push(Qt.resolvedUrl("NewDeviceWizard.qml"))
onButtonClicked: pageStack.push(Qt.resolvedUrl("thingconfiguration/NewThingPage.qml"))
}
}
@ -146,7 +146,7 @@ Page {
buttonText: engine.deviceManager.devices.count === 0 ? qsTr("Add a thing") : qsTr("Add a scene")
onButtonClicked: {
if (engine.deviceManager.devices.count === 0) {
pageStack.push(Qt.resolvedUrl("NewDeviceWizard.qml"))
pageStack.push(Qt.resolvedUrl("thingconfiguration/NewThingPage.qml"))
} else {
var page = pageStack.push(Qt.resolvedUrl("MagicPage.qml"))
page.addRule()

View File

@ -42,13 +42,18 @@ Page {
id: vendorFilterComboBox
Layout.fillWidth: true
textRole: "displayName"
VendorsProxy {
id: vendorsProxy
vendors: engine.deviceManager.vendors
}
model: ListModel {
id: vendorsFilterModel
ListElement { displayName: qsTr("All"); vendorId: "" }
Component.onCompleted: {
for (var i = 0; i < engine.deviceManager.vendors.count; i++) {
var vendor = engine.deviceManager.vendors.get(i);
for (var i = 0; i < vendorsProxy.count; i++) {
var vendor = vendorsProxy.get(i);
append({displayName: vendor.displayName, vendorId: vendor.id})
}
}

View File

@ -28,7 +28,7 @@ Page {
HeaderButton {
imageSource: "../images/close.svg"
onClicked: pageStack.pop();
onClicked: root.done();
}
}
@ -72,7 +72,6 @@ Page {
break;
default:
print("Setup method", params["setupMethod"], "not handled");
}
}
onConfirmPairingReply: {
@ -176,7 +175,13 @@ Page {
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
model: discovery
model: DeviceDiscoveryProxy {
id: discoveryProxy
deviceDiscovery: discovery
showAlreadyAdded: root.device !== null
showNew: root.device === null
filterDeviceId: root.device !== null ? root.device.id : null
}
delegate: MeaListItemDelegate {
width: parent.width
height: app.delegateHeight
@ -184,14 +189,26 @@ Page {
subText: model.description
iconName: app.interfacesToIcon(discoveryView.deviceClass.interfaces)
onClicked: {
d.deviceDescriptor = discovery.get(index);
d.deviceDescriptor = discoveryProxy.get(index);
d.deviceName = model.name;
// Overriding params for reconfiguring discovered devices not supported by core yet
// So if we are reconfiguring and discovering, go straight to end
if (root.device && d.deviceDescriptor) {
busyOverlay.shown = true;
engine.deviceManager.reconfigureDiscoveredDevice(root.device.id, d.deviceDescriptor.id);
switch (root.deviceClass.setupMethod) {
case 0:
engine.deviceManager.reconfigureDiscoveredDevice(root.device.id, d.deviceDescriptor.id);
break;
case 1:
case 2:
case 3:
engine.deviceManager.pairDevice(root.deviceClass.id, d.deviceDescriptor.id, root.device.name);
break;
}
return;
}
@ -205,7 +222,7 @@ Page {
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
text: qsTr("Search again")
onClicked: discovery.discoverDevices(root.deviceClass.id, d.discoveryParams)
visible: !discovery.busy && discovery.count > 0
visible: !discovery.busy && discoveryProxy.count > 0
}
Button {
@ -239,7 +256,7 @@ Page {
ColumnLayout {
anchors.centerIn: parent
width: parent.width - app.margins * 2
visible: !discovery.busy && discovery.count == 0
visible: !discovery.busy && discoveryProxy.count === 0
spacing: app.margins * 2
Label {
text: qsTr("Too bad...")