diff --git a/libnymea-app-core/devices.cpp b/libnymea-app-core/devices.cpp index 2b41170a..1b231155 100644 --- a/libnymea-app-core/devices.cpp +++ b/libnymea-app-core/devices.cpp @@ -127,6 +127,9 @@ QVariant Devices::data(const QModelIndex &index, int role) const if (interfaces.contains("evcharger")) { return "evcharger"; } + if (interfaces.contains("powersocket")) { + return "powersocket"; + } return "uncategorized"; } diff --git a/nymea-app/images.qrc b/nymea-app/images.qrc index bf1b791c..e83d1940 100644 --- a/nymea-app/images.qrc +++ b/nymea-app/images.qrc @@ -168,5 +168,6 @@ ui/images/stock_music.svg ui/images/stock_video.svg ui/images/sensors/presence.svg + ui/images/powersocket.svg diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc index 01200294..e59eda11 100644 --- a/nymea-app/resources.qrc +++ b/nymea-app/resources.qrc @@ -145,5 +145,6 @@ ui/system/ServerConfigurationDialog.qml ui/system/MqttPolicyPage.qml ui/devicepages/BoolSensorDevicePage.qml + ui/devicepages/PowersocketDevicePage.qml diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml index 2239f8e1..8c37124e 100644 --- a/nymea-app/ui/Nymea.qml +++ b/nymea-app/ui/Nymea.qml @@ -52,7 +52,7 @@ ApplicationWindow { rootItem.handleCloseEvent(close) } - property var supportedInterfaces: ["light", "weather", "sensor", "media", "garagegate", "awning", "shutter", "blind", "heating", "smartmeter", "evcharger", "accesscontrol", "button", "notifications", "inputtrigger", "outputtrigger", "gateway"] + property var supportedInterfaces: ["light", "weather", "sensor", "media", "garagegate", "awning", "shutter", "blind", "heating", "smartmeter", "evcharger", "accesscontrol", "button", "powersocket", "notifications", "inputtrigger", "outputtrigger", "gateway"] function interfaceToString(name) { switch(name) { case "light": @@ -106,6 +106,8 @@ ApplicationWindow { return qsTr("Heatings"); case "evcharger": return qsTr("EV-chargers"); + case "powersocket": + return qsTr("Power sockets") case "uncategorized": return qsTr("Uncategorized") default: @@ -155,6 +157,8 @@ ApplicationWindow { case "media": case "mediacontroller": return Qt.resolvedUrl("images/mediaplayer-app-symbolic.svg") + case "powersocket": + return Qt.resolvedUrl("images/powersocket.svg") case "button": case "longpressbutton": case "simplemultibutton": @@ -284,6 +288,8 @@ ApplicationWindow { page = "FingerprintReaderDevicePage.qml"; } else if (interfaceList.indexOf("smartmeter") >= 0) { page = "SmartMeterDevicePage.qml" + } else if (interfaceList.indexOf("powersocket") >= 0) { + page = "PowersocketDevicePage.qml"; } else { page = "GenericDevicePage.qml"; } diff --git a/nymea-app/ui/devicepages/PowersocketDevicePage.qml b/nymea-app/ui/devicepages/PowersocketDevicePage.qml new file mode 100644 index 00000000..ebb8e9a2 --- /dev/null +++ b/nymea-app/ui/devicepages/PowersocketDevicePage.qml @@ -0,0 +1,62 @@ +import QtQuick 2.5 +import QtQuick.Controls 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Material 2.1 +import Nymea 1.0 +import "../components" + +DevicePageBase { + id: root + + readonly property var powerStateType: deviceClass.stateTypes.findByName("power") + readonly property var powerState: device.states.getState(powerStateType.id) + readonly property var powerActionType: deviceClass.actionTypes.findByName("power"); + + GridLayout { + anchors.fill: parent + anchors.margins: app.margins + columns: app.landscape ? 2 : 1 + rowSpacing: app.margins + columnSpacing: app.margins + Layout.alignment: Qt.AlignCenter + + Item { + Layout.preferredWidth: Math.max(app.iconSize * 4, parent.width / 5) + Layout.preferredHeight: width + Layout.topMargin: app.margins + Layout.bottomMargin: app.landscape ? app.margins : 0 + Layout.alignment: Qt.AlignCenter + Layout.rowSpan: app.landscape ? 4 : 1 + Layout.fillHeight: true + + AbstractButton { + height: Math.min(parent.height, parent.width) + width: height + anchors.centerIn: parent + Rectangle { + anchors.fill: parent + color: "white" + border.color: root.powerState.value === true ? app.accentColor : bulbIcon.keyColor + border.width: 4 + radius: width / 2 + } + + ColorIcon { + id: bulbIcon + anchors.fill: parent + anchors.margins: app.margins * 1.5 + name: "../images/powersocket.svg" + color: root.powerState.value === true ? app.accentColor : keyColor + } + onClicked: { + var params = [] + var param = {} + param["paramTypeId"] = root.powerActionType.paramTypes.get(0).id; + param["value"] = !root.powerState.value; + params.push(param) + engine.deviceManager.executeAction(root.device.id, root.powerStateType.id, params); + } + } + } + } +} diff --git a/nymea-app/ui/images/powersocket.svg b/nymea-app/ui/images/powersocket.svg new file mode 100644 index 00000000..4a4da53a --- /dev/null +++ b/nymea-app/ui/images/powersocket.svg @@ -0,0 +1,120 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/nymea-app/ui/mainviews/DevicesPageDelegate.qml b/nymea-app/ui/mainviews/DevicesPageDelegate.qml index a5f94f49..7e1d67b8 100644 --- a/nymea-app/ui/mainviews/DevicesPageDelegate.qml +++ b/nymea-app/ui/mainviews/DevicesPageDelegate.qml @@ -98,6 +98,7 @@ MainPageTile { case "extendedshutter": case "awning": case "extendedawning": + case "powersocket": return buttonComponent default: console.warn("DevicesPageDelegate, inlineControl: Unhandled interface", model.name) @@ -119,6 +120,7 @@ MainPageTile { case "media": return devicesProxy.get(0).name; case "light": + case "powersocket": var count = 0; for (var i = 0; i < devicesProxy.count; i++) { var device = devicesProxy.get(i); @@ -289,6 +291,7 @@ MainPageTile { state.value === "Paused" ? "../images/media-playback-start.svg" : "" case "light": + case "powersocket": return "../images/system-shutdown.svg" case "garagegate": case "blind": @@ -307,6 +310,7 @@ MainPageTile { onClicked: { switch (model.name) { case "light": + case "powersocket": if (devicesProxy.count == 1) { var device = devicesProxy.get(0); var deviceClass = engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);