Add support for reconfiguring devices

This commit is contained in:
Michael Zanetti 2019-01-21 13:47:18 +01:00
parent f095a2ac15
commit 03745e8d9f
10 changed files with 266 additions and 219 deletions

View File

@ -628,7 +628,7 @@ void AWSClient::registerPushNotificationEndpoint(const QString &registrationId,
payload.insert("mobileDeviceUuid", mobileDeviceId); payload.insert("mobileDeviceUuid", mobileDeviceId);
QJsonDocument jsonDoc = QJsonDocument::fromVariant(payload); QJsonDocument jsonDoc = QJsonDocument::fromVariant(payload);
qDebug() << "Registering push notification endpoint"; qDebug() << "Registering push notification endpoint" << mobileDeviceId;
// qDebug() << "POST" << url.toString(); // qDebug() << "POST" << url.toString();
// qDebug() << "HEADERS:"; // qDebug() << "HEADERS:";
// foreach (const QByteArray &hdr, request.rawHeaderList()) { // foreach (const QByteArray &hdr, request.rawHeaderList()) {

View File

@ -302,6 +302,12 @@ void DeviceManager::executeActionResponse(const QVariantMap &params)
emit executeActionReply(params); emit executeActionReply(params);
} }
void DeviceManager::reconfigureDeviceResponse(const QVariantMap &params)
{
qDebug() << "Reconfigure device response" << params;
emit reconfigureDeviceReply(params.value("params").toMap());
}
void DeviceManager::savePluginConfig(const QUuid &pluginId) void DeviceManager::savePluginConfig(const QUuid &pluginId)
{ {
Plugin *p = m_plugins->getPlugin(pluginId); Plugin *p = m_plugins->getPlugin(pluginId);
@ -369,6 +375,22 @@ void DeviceManager::editDevice(const QUuid &deviceId, const QString &name)
m_jsonClient->sendCommand("Devices.EditDevice", params, this, "editDeviceResponse"); m_jsonClient->sendCommand("Devices.EditDevice", params, this, "editDeviceResponse");
} }
void DeviceManager::reconfigureDevice(const QUuid &deviceId, const QVariantList &deviceParams)
{
QVariantMap params;
params.insert("deviceId", deviceId.toString());
params.insert("deviceParams", deviceParams);
m_jsonClient->sendCommand("Devices.ReconfigureDevice", params, this, "reconfigureDeviceResponse");
}
void DeviceManager::reconfigureDiscoveredDevice(const QUuid &deviceId, const QUuid &deviceDescriptorId)
{
QVariantMap params;
params.insert("deviceId", deviceId.toString());
params.insert("deviceDescriptorId", deviceDescriptorId);
m_jsonClient->sendCommand("Devices.ReconfigureDevice", params, this, "reconfigureDeviceResponse");
}
int DeviceManager::executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params) int DeviceManager::executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params)
{ {
// qDebug() << "JsonRpc: execute action " << deviceId.toString() << actionTypeId.toString() << params; // qDebug() << "JsonRpc: execute action " << deviceId.toString() << actionTypeId.toString() << params;

View File

@ -69,6 +69,8 @@ public:
Q_INVOKABLE void confirmPairing(const QUuid &pairingTransactionId, const QString &secret = QString()); Q_INVOKABLE void confirmPairing(const QUuid &pairingTransactionId, const QString &secret = QString());
Q_INVOKABLE void removeDevice(const QUuid &deviceId, RemovePolicy policy = RemovePolicyNone); Q_INVOKABLE void removeDevice(const QUuid &deviceId, RemovePolicy policy = RemovePolicyNone);
Q_INVOKABLE void editDevice(const QUuid &deviceId, const QString &name); Q_INVOKABLE void editDevice(const QUuid &deviceId, const QString &name);
Q_INVOKABLE void reconfigureDevice(const QUuid &deviceId, const QVariantList &deviceParams);
Q_INVOKABLE void reconfigureDiscoveredDevice(const QUuid &deviceId, const QUuid &deviceDescriptorId);
Q_INVOKABLE int executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params = QVariantList()); Q_INVOKABLE int executeAction(const QUuid &deviceId, const QUuid &actionTypeId, const QVariantList &params = QVariantList());
private: private:
@ -85,6 +87,7 @@ private:
Q_INVOKABLE void setPluginConfigResponse(const QVariantMap &params); Q_INVOKABLE void setPluginConfigResponse(const QVariantMap &params);
Q_INVOKABLE void editDeviceResponse(const QVariantMap &params); Q_INVOKABLE void editDeviceResponse(const QVariantMap &params);
Q_INVOKABLE void executeActionResponse(const QVariantMap &params); Q_INVOKABLE void executeActionResponse(const QVariantMap &params);
Q_INVOKABLE void reconfigureDeviceResponse(const QVariantMap &params);
public slots: public slots:
void savePluginConfig(const QUuid &pluginId); void savePluginConfig(const QUuid &pluginId);
@ -96,6 +99,7 @@ signals:
void removeDeviceReply(const QVariantMap &params); void removeDeviceReply(const QVariantMap &params);
void savePluginConfigReply(const QVariantMap &params); void savePluginConfigReply(const QVariantMap &params);
void editDeviceReply(const QVariantMap &params); void editDeviceReply(const QVariantMap &params);
void reconfigureDeviceReply(const QVariantMap &params);
void executeActionReply(const QVariantMap &params); void executeActionReply(const QVariantMap &params);
void fetchingDataChanged(); void fetchingDataChanged();
void notificationReceived(const QString &deviceId, const QString &eventTypeId, const QVariantList &params); void notificationReceived(const QString &deviceId, const QString &eventTypeId, const QVariantList &params);

View File

@ -78,6 +78,8 @@ int main(int argc, char *argv[])
QLibraryInfo::location(QLibraryInfo::TranslationsPath)); QLibraryInfo::location(QLibraryInfo::TranslationsPath));
application.installTranslator(&qtTranslator); application.installTranslator(&qtTranslator);
qDebug() << "Locale info:" << QLocale() << QLocale().name() << QLocale().language() << QLocale().system();
QTranslator appTranslator; QTranslator appTranslator;
bool translationResult = appTranslator.load(QLocale(), "nymea-app", "-", ":/translations/", ".qm"); bool translationResult = appTranslator.load(QLocale(), "nymea-app", "-", ":/translations/", ".qm");
if (translationResult) { if (translationResult) {

View File

@ -1,11 +1,9 @@
<RCC> <RCC>
<qresource prefix="/"> <qresource prefix="/">
<file>ui/Nymea.qml</file> <file>ui/Nymea.qml</file>
<file>ui/NewDeviceWizard.qml</file>
<file>ui/SettingsPage.qml</file> <file>ui/SettingsPage.qml</file>
<file>ui/LoginPage.qml</file> <file>ui/LoginPage.qml</file>
<file>ui/MagicPage.qml</file> <file>ui/MagicPage.qml</file>
<file>ui/EditDevicesPage.qml</file>
<file>ui/PushButtonAuthPage.qml</file> <file>ui/PushButtonAuthPage.qml</file>
<file>ui/KeyboardLoader.qml</file> <file>ui/KeyboardLoader.qml</file>
<file>ui/MainPage.qml</file> <file>ui/MainPage.qml</file>
@ -69,7 +67,6 @@
<file>ui/devicepages/SensorDevicePagePre110.qml</file> <file>ui/devicepages/SensorDevicePagePre110.qml</file>
<file>ui/devicepages/SensorDevicePagePost110.qml</file> <file>ui/devicepages/SensorDevicePagePost110.qml</file>
<file>ui/devicepages/DevicePageBase.qml</file> <file>ui/devicepages/DevicePageBase.qml</file>
<file>ui/devicepages/ConfigureThingPage.qml</file>
<file>ui/devicepages/InputTriggerDevicePage.qml</file> <file>ui/devicepages/InputTriggerDevicePage.qml</file>
<file>ui/devicepages/StateLogPage.qml</file> <file>ui/devicepages/StateLogPage.qml</file>
<file>ui/devicepages/ShutterDevicePage.qml</file> <file>ui/devicepages/ShutterDevicePage.qml</file>
@ -144,10 +141,10 @@
<file>ui/system/ServerConfigurationDialog.qml</file> <file>ui/system/ServerConfigurationDialog.qml</file>
<file>ui/system/MqttPolicyPage.qml</file> <file>ui/system/MqttPolicyPage.qml</file>
<file>ui/devicepages/BoolSensorDevicePage.qml</file> <file>ui/devicepages/BoolSensorDevicePage.qml</file>
<file>ui/devicepages/HeatingDevicePage.qml</file>
<file>ui/devicepages/PowersocketDevicePage.qml</file> <file>ui/devicepages/PowersocketDevicePage.qml</file>
<file>ui/devicelistpages/PowerSocketsDeviceListPage.qml</file> <file>ui/devicelistpages/PowerSocketsDeviceListPage.qml</file>
<file>ui/components/GroupedListView.qml</file> <file>ui/components/GroupedListView.qml</file>
<file>ui/devicepages/HeatingDevicePage.qml</file>
<file>ui/delegates/statedelegates/LedDelegate.qml</file> <file>ui/delegates/statedelegates/LedDelegate.qml</file>
<file>ui/delegates/statedelegates/LabelDelegate.qml</file> <file>ui/delegates/statedelegates/LabelDelegate.qml</file>
<file>ui/delegates/statedelegates/NumberLabelDelegate.qml</file> <file>ui/delegates/statedelegates/NumberLabelDelegate.qml</file>
@ -161,5 +158,9 @@
<file>ui/delegates/statedelegates/DateTimeDelegate.qml</file> <file>ui/delegates/statedelegates/DateTimeDelegate.qml</file>
<file>ui/components/Dial.qml</file> <file>ui/components/Dial.qml</file>
<file>ui/delegates/statedelegates/SliderDelegate.qml</file> <file>ui/delegates/statedelegates/SliderDelegate.qml</file>
<file>ui/thingconfiguration/NewThingPage.qml</file>
<file>ui/thingconfiguration/SetupWizard.qml</file>
<file>ui/thingconfiguration/EditThingsPage.qml</file>
<file>ui/thingconfiguration/ConfigureThingPage.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -15,7 +15,7 @@ Page {
title: swipeView.currentItem.title title: swipeView.currentItem.title
model: ListModel { model: ListModel {
ListElement { iconSource: "../images/share.svg"; text: qsTr("Configure things"); page: "EditDevicesPage.qml" } ListElement { iconSource: "../images/share.svg"; text: qsTr("Configure things"); page: "thingconfiguration/EditThingsPage.qml" }
ListElement { iconSource: "../images/magic.svg"; text: qsTr("Magic"); page: "MagicPage.qml" } ListElement { iconSource: "../images/magic.svg"; text: qsTr("Magic"); page: "MagicPage.qml" }
ListElement { iconSource: "../images/stock_application.svg"; text: qsTr("App settings"); page: "appsettings/AppSettingsPage.qml" } ListElement { iconSource: "../images/stock_application.svg"; text: qsTr("App settings"); page: "appsettings/AppSettingsPage.qml" }
ListElement { iconSource: "../images/settings.svg"; text: qsTr("Box settings"); page: "SettingsPage.qml" } ListElement { iconSource: "../images/settings.svg"; text: qsTr("Box settings"); page: "SettingsPage.qml" }

View File

@ -7,8 +7,8 @@ import "../delegates"
Page { Page {
id: root id: root
property var device: null property Device device: null
readonly property var deviceClass: engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) readonly property DeviceClass deviceClass: device ? device.deviceClass : null
header: GuhHeader { header: GuhHeader {
text: root.device.name text: root.device.name
@ -37,6 +37,15 @@ Page {
popup.open(); popup.open();
} }
} }
IconMenuItem {
iconSource: "../images/configure.svg"
text: qsTr("Reconfigure Thing")
visible: root.device.deviceClass.paramTypes.count > 0
onTriggered: {
var configPage = pageStack.push(Qt.resolvedUrl("SetupWizard.qml"), {device: root.device})
configPage.done.connect(function() {pageStack.pop(root)})
}
}
} }
Connections { Connections {
@ -149,4 +158,5 @@ Page {
} }
} }
} }

View File

@ -1,8 +1,8 @@
import QtQuick 2.4 import QtQuick 2.4
import QtQuick.Controls 2.1 import QtQuick.Controls 2.1
import QtQuick.Layouts 1.2 import QtQuick.Layouts 1.2
import "components" import "../components"
import "delegates" import "../delegates"
import Nymea 1.0 import Nymea 1.0
Page { Page {
@ -20,7 +20,7 @@ Page {
HeaderButton { HeaderButton {
imageSource: "../images/add.svg" imageSource: "../images/add.svg"
onClicked: pageStack.push(Qt.resolvedUrl("NewDeviceWizard.qml")) onClicked: pageStack.push(Qt.resolvedUrl("NewThingPage.qml"))
} }
} }
@ -77,7 +77,7 @@ Page {
canDelete: true canDelete: true
onClicked: { onClicked: {
print("clicked:", model.id) print("clicked:", model.id)
pageStack.push(Qt.resolvedUrl("devicepages/ConfigureThingPage.qml"), {device: device}) pageStack.push(Qt.resolvedUrl("ConfigureThingPage.qml"), {device: device})
} }
onDeleteClicked: { onDeleteClicked: {
d.deviceToRemove = device; d.deviceToRemove = device;
@ -96,6 +96,6 @@ Page {
text: qsTr("In order for your %1 box to be useful, go ahead and add some things.").arg(app.systemName) text: 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) imageSource: "qrc:/styles/%1/logo.svg".arg(styleController.currentStyle)
buttonText: qsTr("Add a thing") buttonText: qsTr("Add a thing")
onButtonClicked: pageStack.push(Qt.resolvedUrl("NewDeviceWizard.qml")) onButtonClicked: pageStack.push(Qt.resolvedUrl("NewThingPage.qml"))
} }
} }

View File

@ -0,0 +1,125 @@
import QtQuick 2.5
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1
import Nymea 1.0
import "../components"
import "../delegates"
Page {
id: root
header: GuhHeader {
text: qsTr("Set up new thing")
onBackPressed: {
pageStack.pop();
}
}
Pane {
id: filterPane
anchors { left: parent.left; top: parent.top; right: parent.right }
Behavior on height { NumberAnimation { duration: 120; easing.type: Easing.InOutQuad } }
height: implicitHeight + app.margins * 2
Material.elevation: 1
z: 1
leftPadding: 0; rightPadding: 0; topPadding: 0; bottomPadding: 0
contentItem: Rectangle {
color: app.primaryColor
clip: true
GridLayout {
anchors.fill: parent
anchors.margins: app.margins
columnSpacing: app.margins
columns: 2
Label {
text: qsTr("Vendor")
}
ComboBox {
id: vendorFilterComboBox
Layout.fillWidth: true
textRole: "displayName"
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);
append({displayName: vendor.displayName, vendorId: vendor.id})
}
}
}
}
Label {
text: qsTr("Type")
}
ComboBox {
id: typeFilterComboBox
Layout.fillWidth: true
textRole: "displayName"
InterfacesSortModel {
id: interfacesSortModel
interfacesModel: InterfacesModel {
deviceManager: engine.deviceManager
shownInterfaces: app.supportedInterfaces
onlyConfiguredDevices: false
showUncategorized: false
}
}
model: ListModel {
id: typeFilterModel
ListElement { interfaceName: ""; displayName: qsTr("All") }
Component.onCompleted: {
for (var i = 0; i < interfacesSortModel.count; i++) {
append({interfaceName: interfacesSortModel.get(i), displayName: app.interfaceToString(interfacesSortModel.get(i))});
}
}
}
}
}
}
}
GroupedListView {
anchors {
left: parent.left
top: filterPane.bottom
right: parent.right
bottom: parent.bottom
}
model: DeviceClassesProxy {
id: deviceClassesProxy
vendorId: vendorsFilterModel.get(vendorFilterComboBox.currentIndex).vendorId
deviceClasses: engine.deviceManager.deviceClasses
filterInterface: typeFilterModel.get(typeFilterComboBox.currentIndex).interfaceName
groupByInterface: true
}
delegate: MeaListItemDelegate {
id: deviceClassDelegate
width: parent.width
text: model.displayName
subText: engine.deviceManager.vendors.getVendor(model.vendorId).displayName
iconName: app.interfacesToIcon(deviceClass.interfaces)
prominentSubText: false
wrapTexts: false
property var deviceClass: deviceClassesProxy.get(index)
onClicked: {
var page = pageStack.push(Qt.resolvedUrl("SetupWizard.qml"), {deviceClass: deviceClassesProxy.get(index)});
page.done.connect(function() {
pageStack.pop(root, StackView.Immediate);
pageStack.pop();
})
}
}
}
}

View File

@ -3,17 +3,27 @@ import QtQuick.Layouts 1.1
import QtQuick.Controls 2.1 import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.1 import QtQuick.Controls.Material 2.1
import Nymea 1.0 import Nymea 1.0
import "components" import "../components"
import "delegates" import "../delegates"
Page { Page {
id: root id: root
property DeviceClass deviceClass: device ? device.deviceClass : null
// Optional: If set, it will be reconfigred, otherwise a new one will be created
property Device device: null
signal done();
header: GuhHeader { header: GuhHeader {
text: qsTr("Set up new thing") text: qsTr("Set up thing")
backButtonVisible: internalPageStack.depth > 1
onBackPressed: { onBackPressed: {
internalPageStack.pop(); if (internalPageStack.depth > 1) {
internalPageStack.pop();
} else {
pageStack.pop();
}
} }
HeaderButton { HeaderButton {
@ -25,7 +35,6 @@ Page {
QtObject { QtObject {
id: d id: d
property var vendorId: null property var vendorId: null
property DeviceClass deviceClass: null
property DeviceDescriptor deviceDescriptor: null property DeviceDescriptor deviceDescriptor: null
property var discoveryParams: [] property var discoveryParams: []
property string deviceName: "" property string deviceName: ""
@ -34,6 +43,19 @@ Page {
property int addRequestId: 0 property int addRequestId: 0
} }
Component.onCompleted: {
if (root.deviceClass.createMethods.indexOf("CreateMethodDiscovery") !== -1) {
if (deviceClass["discoveryParamTypes"].count > 0) {
internalPageStack.push(discoveryParamsPage)
} else {
discovery.discoverDevices(deviceClass.id)
internalPageStack.push(discoveryPage, {deviceClass: deviceClass})
}
} else if (deviceClass.createMethods.indexOf("CreateMethodUser") !== -1) {
internalPageStack.push(paramsPage)
}
}
Connections { Connections {
target: engine.deviceManager target: engine.deviceManager
onPairDeviceReply: { onPairDeviceReply: {
@ -61,6 +83,10 @@ Page {
busyOverlay.shown = false; busyOverlay.shown = false;
internalPageStack.push(resultsPage, {success: params["deviceError"] === "DeviceErrorNoError", deviceId: params["deviceId"]}) internalPageStack.push(resultsPage, {success: params["deviceError"] === "DeviceErrorNoError", deviceId: params["deviceId"]})
} }
onReconfigureDeviceReply: {
busyOverlay.shown = false;
internalPageStack.push(resultsPage, {success: params["deviceError"] === "DeviceErrorNoError", deviceId: params["deviceId"]})
}
} }
DeviceDiscovery { DeviceDiscovery {
@ -71,169 +97,6 @@ Page {
StackView { StackView {
id: internalPageStack id: internalPageStack
anchors.fill: parent anchors.fill: parent
Component.onCompleted: push(deviceClassesPage)
}
Component {
id: vendorsPage
Page {
ListView {
anchors.fill: parent
model: VendorsProxy {
vendors: engine.deviceManager.vendors
}
delegate: MeaListItemDelegate {
width: parent.width
text: model.displayName
onClicked: {
d.vendorId = model.id
internalPageStack.push(deviceClassesPage)
}
}
}
}
}
Component {
id: deviceClassesPage
Page {
Pane {
id: filterPane
anchors { left: parent.left; top: parent.top; right: parent.right }
Behavior on height { NumberAnimation { duration: 120; easing.type: Easing.InOutQuad } }
height: implicitHeight + app.margins * 2
Material.elevation: 1
z: 1
leftPadding: 0; rightPadding: 0; topPadding: 0; bottomPadding: 0
contentItem: Rectangle {
color: app.primaryColor
clip: true
GridLayout {
anchors.fill: parent
anchors.margins: app.margins
columnSpacing: app.margins
columns: 2
Label {
text: qsTr("Vendor")
}
ComboBox {
id: vendorFilterComboBox
Layout.fillWidth: true
textRole: "displayName"
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);
append({displayName: vendor.displayName, vendorId: vendor.id})
}
}
}
}
Label {
text: qsTr("Type")
}
ComboBox {
id: typeFilterComboBox
Layout.fillWidth: true
textRole: "displayName"
InterfacesSortModel {
id: interfacesSortModel
interfacesModel: InterfacesModel {
deviceManager: engine.deviceManager
shownInterfaces: app.supportedInterfaces
onlyConfiguredDevices: false
showUncategorized: false
}
}
model: ListModel {
id: typeFilterModel
ListElement { interfaceName: ""; displayName: qsTr("All") }
Component.onCompleted: {
for (var i = 0; i < interfacesSortModel.count; i++) {
append({interfaceName: interfacesSortModel.get(i), displayName: app.interfaceToString(interfacesSortModel.get(i))});
}
}
}
}
}
}
}
GroupedListView {
anchors {
left: parent.left
top: filterPane.bottom
right: parent.right
bottom: parent.bottom
}
model: DeviceClassesProxy {
id: deviceClassesProxy
vendorId: vendorsFilterModel.get(vendorFilterComboBox.currentIndex).vendorId
deviceClasses: engine.deviceManager.deviceClasses
filterInterface: typeFilterModel.get(typeFilterComboBox.currentIndex).interfaceName
groupByInterface: true
}
delegate: MeaListItemDelegate {
id: deviceClassDelegate
width: parent.width
text: model.displayName
subText: engine.deviceManager.vendors.getVendor(model.vendorId).displayName
iconName: app.interfacesToIcon(deviceClass.interfaces)
prominentSubText: false
wrapTexts: false
property var deviceClass: deviceClassesProxy.get(index)
onClicked: {
d.deviceClass = deviceClass
if (deviceClass.createMethods.indexOf("CreateMethodDiscovery") !== -1) {
if (deviceClass["discoveryParamTypes"].count > 0) {
internalPageStack.push(discoveryParamsPage)
} else {
discovery.discoverDevices(deviceClass.id)
internalPageStack.push(discoveryPage, {deviceClass: deviceClass})
}
} else if (deviceClass.createMethods.indexOf("CreateMethodUser") !== -1) {
internalPageStack.push(paramsPage)
}
print("should setup", deviceClass.name, deviceClass.setupMethod, deviceClass.createMethods, deviceClass["discoveryParamTypes"].count)
}
swipe.enabled: deviceClass.createMethods.indexOf("CreateMethodUser") !== -1
swipe.right: MouseArea {
height: deviceClassDelegate.height
width: height
anchors.right: parent.right
Rectangle {
anchors.fill: parent
color: "transparent"
}
ColorIcon {
anchors.fill: parent
anchors.margins: app.margins
name: "../images/add.svg"
}
onClicked: {
d.deviceClass = deviceClass
internalPageStack.push(paramsPage)
}
}
}
}
}
} }
Component { Component {
@ -254,7 +117,7 @@ Page {
Repeater { Repeater {
id: paramRepeater id: paramRepeater
model: d.deviceClass ? d.deviceClass["discoveryParamTypes"] : null model: root.deviceClass ? root.deviceClass["discoveryParamTypes"] : null
Loader { Loader {
Layout.fillWidth: true Layout.fillWidth: true
sourceComponent: searchStringEntryComponent sourceComponent: searchStringEntryComponent
@ -266,7 +129,7 @@ Page {
Layout.fillWidth: true Layout.fillWidth: true
text: "Next" text: "Next"
onClicked: { onClicked: {
var paramTypes = d.deviceClass["discoveryParamTypes"]; var paramTypes = root.deviceClass["discoveryParamTypes"];
d.discoveryParams = []; d.discoveryParams = [];
for (var i = 0; i < paramTypes.count; i++) { for (var i = 0; i < paramTypes.count; i++) {
var param = {}; var param = {};
@ -274,8 +137,8 @@ Page {
param["value"] = paramRepeater.itemAt(i).value param["value"] = paramRepeater.itemAt(i).value
d.discoveryParams.push(param); d.discoveryParams.push(param);
} }
discovery.discoverDevices(d.deviceClass.id, d.discoveryParams) discovery.discoverDevices(root.deviceClass.id, d.discoveryParams)
internalPageStack.push(discoveryPage, {deviceClass: d.deviceClass}) internalPageStack.push(discoveryPage, {deviceClass: root.deviceClass})
} }
} }
} }
@ -323,6 +186,15 @@ Page {
onClicked: { onClicked: {
d.deviceDescriptor = discovery.get(index); d.deviceDescriptor = discovery.get(index);
d.deviceName = model.name; 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);
return;
}
internalPageStack.push(paramsPage) internalPageStack.push(paramsPage)
} }
} }
@ -332,7 +204,7 @@ Page {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
text: qsTr("Search again") text: qsTr("Search again")
onClicked: discovery.discoverDevices(d.deviceClass.id, d.discoveryParams) onClicked: discovery.discoverDevices(root.deviceClass.id, d.discoveryParams)
visible: !discovery.busy && discovery.count > 0 visible: !discovery.busy && discovery.count > 0
} }
@ -340,7 +212,7 @@ Page {
id: manualAddButton id: manualAddButton
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins Layout.leftMargin: app.margins; Layout.rightMargin: app.margins; Layout.bottomMargin: app.margins
visible: d.deviceClass.createMethods.indexOf("CreateMethodUser") >= 0 visible: root.deviceClass.createMethods.indexOf("CreateMethodUser") >= 0
text: qsTr("Add thing manually") text: qsTr("Add thing manually")
onClicked: internalPageStack.push(paramsPage) onClicked: internalPageStack.push(paramsPage)
} }
@ -389,7 +261,7 @@ Page {
text: qsTr("Try again!") text: qsTr("Try again!")
Layout.fillWidth: true Layout.fillWidth: true
onClicked: { onClicked: {
discovery.discoverDevices(d.deviceClass.id, d.discoveryParams) discovery.discoverDevices(root.deviceClass.id, d.discoveryParams)
} }
} }
} }
@ -409,35 +281,38 @@ Page {
id: paramsColumn id: paramsColumn
width: parent.width width: parent.width
Label { ColumnLayout {
Layout.leftMargin: app.margins visible: root.device === null
Layout.rightMargin: app.margins Label {
Layout.topMargin: app.margins Layout.leftMargin: app.margins
Layout.fillWidth: true Layout.rightMargin: app.margins
text: qsTr("Name the thing:") Layout.topMargin: app.margins
} Layout.fillWidth: true
TextField { text: qsTr("Name the thing:")
id: nameTextField }
text: d.deviceName ? d.deviceName : "" TextField {
Layout.fillWidth: true id: nameTextField
Layout.leftMargin: app.margins text: d.deviceName ? d.deviceName : ""
Layout.rightMargin: app.margins Layout.fillWidth: true
} Layout.leftMargin: app.margins
Layout.rightMargin: app.margins
}
ThinDivider { ThinDivider {
visible: paramRepeater.count > 0 visible: paramRepeater.count > 0
}
} }
Repeater { Repeater {
id: paramRepeater id: paramRepeater
model: engine.jsonRpcClient.ensureServerVersion("1.12") || d.deviceDescriptor == null ? d.deviceClass.paramTypes : null model: engine.jsonRpcClient.ensureServerVersion("1.12") || d.deviceDescriptor == null ? root.deviceClass.paramTypes : null
delegate: ParamDelegate { delegate: ParamDelegate {
// Layout.preferredHeight: 60 // Layout.preferredHeight: 60
Layout.fillWidth: true Layout.fillWidth: true
paramType: d.deviceClass.paramTypes.get(index) paramType: root.deviceClass.paramTypes.get(index)
value: d.deviceDescriptor && d.deviceDescriptor.params.getParam(paramType.id) ? value: d.deviceDescriptor && d.deviceDescriptor.params.getParam(paramType.id) ?
d.deviceDescriptor.params.getParam(paramType.id).value : d.deviceDescriptor.params.getParam(paramType.id).value :
d.deviceClass.paramTypes.get(index).defaultValue root.deviceClass.paramTypes.get(index).defaultValue
} }
} }
@ -448,7 +323,7 @@ Page {
text: "OK" text: "OK"
onClicked: { onClicked: {
print("setupMethod", d.deviceClass.setupMethod) print("setupMethod", root.deviceClass.setupMethod)
var params = [] var params = []
for (var i = 0; i < paramRepeater.count; i++) { for (var i = 0; i < paramRepeater.count; i++) {
@ -459,20 +334,26 @@ Page {
params.push(param) params.push(param)
} }
switch (d.deviceClass.setupMethod) { switch (root.deviceClass.setupMethod) {
case 0: case 0:
if (d.deviceDescriptor) { if (root.device !== null) {
engine.deviceManager.addDiscoveredDevice(d.deviceClass.id, d.deviceDescriptor.id, nameTextField.text, params); if (d.deviceDescriptor) {
engine.deviceManager.reconfigureDiscoveredDevice(root.device.id, d.deviceDescriptor.id);
} else {
engine.deviceManager.reconfigureDevice(root.device.id, params);
}
} else { } else {
if (d.deviceDescriptor) {
engine.deviceManager.addDevice(d.deviceClass.id, nameTextField.text, params); engine.deviceManager.addDiscoveredDevice(root.deviceClass.id, d.deviceDescriptor.id, nameTextField.text, params);
} else {
engine.deviceManager.addDevice(root.deviceClass.id, nameTextField.text, params);
}
} }
break; break;
case 1: case 1:
case 2: case 2:
case 3: case 3:
engine.deviceManager.pairDevice(d.deviceClass.id, d.deviceDescriptor.id, nameTextField.text); engine.deviceManager.pairDevice(root.deviceClass.id, d.deviceDescriptor.id, nameTextField.text);
break; break;
} }
@ -539,7 +420,7 @@ Page {
property bool success property bool success
property string deviceId property string deviceId
readonly property var device: engine.deviceManager.devices.getDevice(deviceId) readonly property var device: root.device ? root.device : engine.deviceManager.devices.getDevice(deviceId)
ColumnLayout { ColumnLayout {
width: parent.width - app.margins * 2 width: parent.width - app.margins * 2
@ -549,7 +430,7 @@ Page {
Layout.fillWidth: true Layout.fillWidth: true
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: resultsView.success ? qsTr("Thing added!") : qsTr("Uh oh") text: resultsView.success ? root.device ? qsTr("Thing reconfigured!") : qsTr("Thing added!") : qsTr("Uh oh")
font.pixelSize: app.largeFont font.pixelSize: app.largeFont
color: app.accentColor color: app.accentColor
} }
@ -563,7 +444,9 @@ Page {
Button { Button {
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Ok") text: qsTr("Ok")
onClicked: pageStack.pop(); onClicked: {
root.done();
}
} }
} }
} }