diff --git a/mea/devicediscovery.cpp b/mea/devicediscovery.cpp index a5aae9be..c495572d 100644 --- a/mea/devicediscovery.cpp +++ b/mea/devicediscovery.cpp @@ -38,6 +38,11 @@ QHash DeviceDiscovery::roleNames() const void DeviceDiscovery::discoverDevices(const QUuid &deviceClassId, const QVariantList &discoveryParams) { + beginResetModel(); + m_foundDevices.clear(); + endResetModel(); + emit countChanged(); + QVariantMap params; params.insert("deviceClassId", deviceClassId.toString()); if (!discoveryParams.isEmpty()) { @@ -46,7 +51,6 @@ void DeviceDiscovery::discoverDevices(const QUuid &deviceClassId, const QVariant Engine::instance()->jsonRpcClient()->sendCommand("Devices.GetDiscoveredDevices", params, this, "discoverDevicesResponse"); m_busy = true; emit busyChanged(); - emit countChanged(); } bool DeviceDiscovery::busy() const diff --git a/mea/devices.cpp b/mea/devices.cpp index 03c1d1f7..9b556f98 100644 --- a/mea/devices.cpp +++ b/mea/devices.cpp @@ -129,7 +129,6 @@ QHash Devices::roleNames() const roles[RoleId] = "id"; roles[RoleDeviceClass] = "deviceClassId"; roles[RoleSetupComplete] = "setupComplete"; - roles[RoleBasicTag] = "basicTag"; roles[RoleInterfaces] = "interfaces"; return roles; } diff --git a/mea/devices.h b/mea/devices.h index 0e745b2d..0f699667 100644 --- a/mea/devices.h +++ b/mea/devices.h @@ -38,7 +38,6 @@ public: RoleId, RoleDeviceClass, RoleSetupComplete, - RoleBasicTag, RoleInterfaces }; Q_ENUM(Roles) diff --git a/mea/devicesproxy.cpp b/mea/devicesproxy.cpp index 1e5be80c..05777c25 100644 --- a/mea/devicesproxy.cpp +++ b/mea/devicesproxy.cpp @@ -39,6 +39,7 @@ void DevicesProxy::setDevices(Devices *devices) if (m_devices != devices) { m_devices = devices; setSourceModel(devices); + setSortRole(Devices::RoleName); sort(0); connect(devices, &Devices::countChanged, this, &DevicesProxy::countChanged); emit devicesChanged(); @@ -83,8 +84,8 @@ Device *DevicesProxy::get(int index) const bool DevicesProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const { - QVariant leftName = sourceModel()->data(left); - QVariant rightName = sourceModel()->data(right); + QVariant leftName = sourceModel()->data(left, Devices::RoleName); + QVariant rightName = sourceModel()->data(right, Devices::RoleName); return QString::localeAwareCompare(leftName.toString(), rightName.toString()) < 0; } diff --git a/mea/discovery/upnpdiscovery.cpp b/mea/discovery/upnpdiscovery.cpp index 7b40f1dd..7c95ae6f 100644 --- a/mea/discovery/upnpdiscovery.cpp +++ b/mea/discovery/upnpdiscovery.cpp @@ -134,8 +134,10 @@ void UpnpDiscovery::readData() data.resize(pendingDatagramSize()); readDatagram(data.data(), data.size(), &hostAddress, &port); } - if (data.contains("10.10.10.128")) - qDebug() << "Data received" << data; + + if (!discovering()) { + return; + } // if the data contains the HTTP OK header... if (data.contains("HTTP/1.1 200 OK") || data.contains("NOTIFY * HTTP/1.1")) { diff --git a/mea/resources.qrc b/mea/resources.qrc index 2c0dd9ae..f13a7539 100644 --- a/mea/resources.qrc +++ b/mea/resources.qrc @@ -150,5 +150,6 @@ ui/images/clock-app-symbolic.svg ui/devicepages/StateLogPage.qml ui/customviews/GenericTypeLogView.qml + guh-logo.svg diff --git a/mea/ui/ConnectPage.qml b/mea/ui/ConnectPage.qml index 8d111c8c..b79223a2 100644 --- a/mea/ui/ConnectPage.qml +++ b/mea/ui/ConnectPage.qml @@ -157,7 +157,6 @@ Page { Dialog { id: certDialog width: Math.min(parent.width * .9, 400) - height: content.height x: (parent.width - width) / 2 y: (parent.height - height) / 2 standardButtons: Dialog.Yes | Dialog.No @@ -167,7 +166,6 @@ Page { ColumnLayout { anchors { left: parent.left; right: parent.right; top: parent.top } - height: childrenRect.height spacing: app.margins RowLayout { diff --git a/mea/ui/MainPage.qml b/mea/ui/MainPage.qml index 9d89f5ac..5f8d046f 100644 --- a/mea/ui/MainPage.qml +++ b/mea/ui/MainPage.qml @@ -15,6 +15,14 @@ Page { onMenuPressed: mainMenu.open() } + Image { + id: bg + source: "../guh-logo.svg" + anchors.fill: parent + fillMode: Image.PreserveAspectFit + opacity: .2 + } + Menu { id: mainMenu width: implicitWidth + app.margins @@ -77,9 +85,13 @@ Page { ListView { width: swipeView.width height: swipeView.height - model: Engine.deviceManager.devices + model: DevicesProxy { + id: devicesProxy + devices: Engine.deviceManager.devices + } delegate: ItemDelegate { width: parent.width + property string mainInterface: app.interfacesToIcon(model.interfaces) contentItem: RowLayout { spacing: app.margins ColorIcon { @@ -93,9 +105,14 @@ Page { Layout.fillWidth: true text: model.name } + Image { + source: "images/next.svg" + Layout.preferredHeight: parent.height + Layout.preferredWidth: height + } } onClicked: { - pageStack.push(Qt.resolvedUrl("devicepages/GenericDevicePage.qml"), {device: Engine.deviceManager.devices.get(index)}) + pageStack.push(Qt.resolvedUrl("devicepages/GenericDevicePage.qml"), {device: devicesProxy.get(index)}) } } @@ -117,7 +134,7 @@ Page { } ColumnLayout { - anchors { left: parent.left; right: parent.right; verticalCenter: parent.verticalCenter; margins: app.margins } + anchors { left: parent.left; right: parent.right; top: parent.top; margins: app.margins } spacing: app.margins visible: Engine.deviceManager.devices.count === 0 && !Engine.deviceManager.fetchingData Label { diff --git a/mea/ui/NewDeviceWizard.qml b/mea/ui/NewDeviceWizard.qml index bb5cacab..8ad6fa80 100644 --- a/mea/ui/NewDeviceWizard.qml +++ b/mea/ui/NewDeviceWizard.qml @@ -34,10 +34,6 @@ Page { property bool addResult: false } - DeviceDiscovery { - id: discovery - } - Connections { target: Engine.deviceManager onPairDeviceReply: { @@ -63,6 +59,10 @@ Page { } } + DeviceDiscovery { + id: discovery + } + StackView { id: internalPageStack anchors.fill: parent @@ -75,14 +75,15 @@ Page { delegate: ItemDelegate { width: parent.width height: app.delegateHeight - ColumnLayout { - anchors.fill: parent - anchors.margins: app.margins + contentItem: RowLayout { Label { - text: model.displayName Layout.fillWidth: true - Layout.fillHeight: true - verticalAlignment: Text.AlignVCenter + text: model.displayName + } + Image { + source: "images/next.svg" + Layout.preferredHeight: parent.height + Layout.preferredWidth: height } } @@ -109,14 +110,15 @@ Page { delegate: ItemDelegate { width: parent.width height: app.delegateHeight - ColumnLayout { - anchors.fill: parent - anchors.margins: app.margins + contentItem: RowLayout { Label { - text: model.displayName Layout.fillWidth: true - Layout.fillHeight: true - verticalAlignment: Text.AlignVCenter + text: model.displayName + } + Image { + source: "images/next.svg" + Layout.preferredHeight: parent.height + Layout.preferredWidth: height } } @@ -145,26 +147,52 @@ Page { Page { id: discoveryParamsView + ColumnLayout { anchors.fill: parent anchors.margins: 10 - Repeater { - id: paramRepeater - model: d.deviceClass ? d.deviceClass["discoveryParamTypes"] : null - Loader { - Layout.fillWidth: true - sourceComponent: searchStringEntryComponent - property var discoveryParams: model - property var value: item ? item.value : null + Flickable { + Layout.fillHeight: true + Layout.fillWidth: true + ColumnLayout { + width: parent.width + + Repeater { + id: paramRepeater + model: d.deviceClass ? d.deviceClass["discoveryParamTypes"] : null + Loader { + Layout.fillWidth: true + sourceComponent: searchStringEntryComponent + property var discoveryParams: model + property var value: item ? item.value : null + } + } + Button { + Layout.fillWidth: true + text: "Next" + onClicked: { + var paramTypes = d.deviceClass["discoveryParamTypes"]; + d.discoveryParams = []; + for (var i = 0; i < paramTypes.count; i++) { + var param = {}; + param["paramTypeId"] = paramTypes.get(i).id; + param["value"] = paramRepeater.itemAt(i).value + d.discoveryParams.push(param); + } + discovery.discoverDevices(d.deviceClass.id, d.discoveryParams) + internalPageStack.push(discoveryPage) + } + } } } + Component { id: searchStringEntryComponent ColumnLayout { property alias value: searchTextField.text Label { - text: discoveryParams.name + text: discoveryParams.displayName Layout.fillWidth: true } TextField { @@ -173,23 +201,6 @@ Page { } } } - - Button { - Layout.fillWidth: true - text: "Next" - onClicked: { - var paramTypes = d.deviceClass["discoveryParamTypes"]; - d.discoveryParams = []; - for (var i = 0; i < paramTypes.count; i++) { - var param = {}; - param["paramTypeId"] = paramTypes.get(i).id; - param["value"] = paramRepeater.itemAt(i).value - d.discoveryParams.push(param); - } - discovery.discoverDevices(d.deviceClass.id, d.discoveryParams) - internalPageStack.push(discoveryPage) - } - } } } } @@ -200,6 +211,7 @@ Page { Page { id: discoveryView + ListView { anchors.fill: parent model: discovery @@ -286,6 +298,7 @@ Page { ColumnLayout { anchors.fill: parent spacing: app.margins + ColumnLayout { Layout.margins: app.margins Layout.fillWidth: true @@ -301,15 +314,19 @@ Page { } ThinDivider {} + Flickable { Layout.fillWidth: true Layout.fillHeight: true + contentHeight: paramsColumn.implicitHeight + clip: true Column { + id: paramsColumn width: parent.width Repeater { id: paramRepeater - model: d.deviceClass.paramTypes + model: d.deviceDescriptorId == null ? d.deviceClass.paramTypes : null delegate: ParamDelegate { width: parent.width paramType: d.deviceClass.paramTypes.get(index) @@ -321,6 +338,8 @@ Page { Button { Layout.fillWidth: true + Layout.margins: app.margins + text: "OK" onClicked: { print("setupMethod", d.deviceClass.setupMethod) diff --git a/mea/ui/SettingsPage.qml b/mea/ui/SettingsPage.qml index c2d40fd5..7535b49a 100644 --- a/mea/ui/SettingsPage.qml +++ b/mea/ui/SettingsPage.qml @@ -103,20 +103,6 @@ Page { color: app.guhAccent } - RowLayout { - Layout.fillWidth: true - Layout.leftMargin: app.margins - Layout.rightMargin: app.margins - spacing: app.margins - Label { - text: qsTr("Debug server enabled") - Layout.fillWidth: true - } - Switch { - checked: Engine.basicConfiguration.debugServerEnabled - onClicked: Engine.basicConfiguration.debugServerEnabled = checked - } - } RowLayout { Layout.fillWidth: true @@ -133,6 +119,25 @@ Page { } } + ColumnLayout { + Layout.fillWidth: true + + RowLayout { + Layout.fillWidth: true + Layout.leftMargin: app.margins + Layout.rightMargin: app.margins + spacing: app.margins + Label { + text: qsTr("Debug server enabled") + Layout.fillWidth: true + } + Switch { + checked: Engine.basicConfiguration.debugServerEnabled + onClicked: Engine.basicConfiguration.debugServerEnabled = checked + } + } + } + ItemDelegate { Layout.fillWidth: true contentItem: RowLayout { @@ -150,6 +155,5 @@ Page { pageStack.push(Qt.resolvedUrl("system/PluginsPage.qml")) } } - } } diff --git a/mea/ui/actiondelegates-ng/ActionDelegate.qml b/mea/ui/actiondelegates-ng/ActionDelegate.qml index 32dc1ba8..898c79fc 100644 --- a/mea/ui/actiondelegates-ng/ActionDelegate.qml +++ b/mea/ui/actiondelegates-ng/ActionDelegate.qml @@ -32,7 +32,11 @@ ItemDelegate { switch (paramType.type.toLowerCase()) { case "bool": return boolComponent; + case "double": case "int": + if (paramType.minValue === undefined || paramType.maxValue === undefined) { + return textFieldComponent + } return stringComponent; case "string": case "qstring": @@ -72,7 +76,7 @@ ItemDelegate { switch (paramType.type.toLowerCase()) { case "int": case "double": - if (paramType.minValue != undefined && paramType.maxValue != undefined) { + if (paramType.minValue !== undefined && paramType.maxValue !== undefined) { return sliderComponent } break; diff --git a/mea/ui/devicepages/ColorLightDevicePage.qml b/mea/ui/devicepages/ColorLightDevicePage.qml index e7162e97..edf11220 100644 --- a/mea/ui/devicepages/ColorLightDevicePage.qml +++ b/mea/ui/devicepages/ColorLightDevicePage.qml @@ -78,21 +78,17 @@ DevicePageBase { } - - - - - - - ColorPickerCt { id: pickerCt Layout.fillWidth: true Layout.margins: app.margins property var actionType: root.deviceClass.actionTypes.findByName("colorTemperature") + property var stateType: root.deviceClass.stateTypes.findByName("colorTemperature") property var ctState: actionType ? root.device.states.getState(actionType.id) : null ct: ctState ? ctState.value : 0 visible: root.deviceClass.interfaces.indexOf("colorlight") >= 0 + minCt: actionType.paramTypes.findByName("colorTemperature").minValue + maxCt: actionType.paramTypes.findByName("colorTemperature").maxValue height: 80