Merge PR #114: Add a custom power socket view
This commit is contained in:
commit
ee2dad9e74
@ -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";
|
||||
}
|
||||
|
||||
|
||||
@ -168,5 +168,6 @@
|
||||
<file>ui/images/stock_music.svg</file>
|
||||
<file>ui/images/stock_video.svg</file>
|
||||
<file>ui/images/sensors/presence.svg</file>
|
||||
<file>ui/images/powersocket.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -145,5 +145,7 @@
|
||||
<file>ui/system/ServerConfigurationDialog.qml</file>
|
||||
<file>ui/system/MqttPolicyPage.qml</file>
|
||||
<file>ui/devicepages/BoolSensorDevicePage.qml</file>
|
||||
<file>ui/devicepages/PowersocketDevicePage.qml</file>
|
||||
<file>ui/devicelistpages/PowerSocketsDeviceListPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -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", "media", "garagegate", "awning", "shutter", "blind", "heating", "powersocket", "sensor", "smartmeter", "evcharger", "accesscontrol", "button", "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";
|
||||
}
|
||||
|
||||
98
nymea-app/ui/devicelistpages/PowerSocketsDeviceListPage.qml
Normal file
98
nymea-app/ui/devicelistpages/PowerSocketsDeviceListPage.qml
Normal file
@ -0,0 +1,98 @@
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import Nymea 1.0
|
||||
import "../components"
|
||||
import "../delegates"
|
||||
import QtQuick.Controls.Material 2.1
|
||||
|
||||
DeviceListPageBase {
|
||||
id: root
|
||||
|
||||
header: GuhHeader {
|
||||
text: qsTr("My %1").arg(app.interfaceToString("powersocket"))
|
||||
|
||||
onBackPressed: {
|
||||
pageStack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: devicesProxy
|
||||
spacing: app.margins
|
||||
|
||||
delegate: Pane {
|
||||
id: itemDelegate
|
||||
width: parent.width
|
||||
|
||||
property var device: devicesProxy.get(index);
|
||||
property var deviceClass: engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId);
|
||||
|
||||
property var connectedStateType: deviceClass.stateTypes.findByName("connected");
|
||||
property var connectedState: connectedStateType ? device.states.getState(connectedStateType.id) : null
|
||||
|
||||
property var powerStateType: deviceClass.stateTypes.findByName("power");
|
||||
property var powerActionType: deviceClass.actionTypes.findByName("power");
|
||||
property var powerState: device.states.getState(powerStateType.id)
|
||||
|
||||
Material.elevation: 1
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
contentItem: ItemDelegate {
|
||||
id: contentItem
|
||||
implicitHeight: nameRow.implicitHeight
|
||||
topPadding: 0
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 0
|
||||
RowLayout {
|
||||
enabled: itemDelegate.connectedState === null || itemDelegate.connectedState.value === true
|
||||
id: nameRow
|
||||
z: 2 // make sure the switch in here is on top of the slider, given we cheated a bit and made them overlap
|
||||
spacing: app.margins
|
||||
Item {
|
||||
Layout.preferredHeight: app.iconSize
|
||||
Layout.preferredWidth: height
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
ColorIcon {
|
||||
id: icon
|
||||
anchors.fill: parent
|
||||
color: itemDelegate.connectedState !== null && itemDelegate.connectedState.value === false
|
||||
? "red"
|
||||
: itemDelegate.powerState.value === true ? app.accentColor : keyColor
|
||||
name: itemDelegate.connectedState !== null && itemDelegate.connectedState.value === false ?
|
||||
"../images/dialog-warning-symbolic.svg"
|
||||
: app.interfaceToIcon("powersocket")
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Switch {
|
||||
checked: itemDelegate.powerState.value === true
|
||||
onClicked: {
|
||||
var params = [];
|
||||
var param1 = {};
|
||||
param1["paramTypeId"] = itemDelegate.powerActionType.paramTypes.get(0).id;
|
||||
param1["value"] = checked;
|
||||
params.push(param1)
|
||||
engine.deviceManager.executeAction(device.id, itemDelegate.powerActionType.id, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
enterPage(index, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
nymea-app/ui/devicepages/PowersocketDevicePage.qml
Normal file
62
nymea-app/ui/devicepages/PowersocketDevicePage.qml
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
120
nymea-app/ui/images/powersocket.svg
Normal file
120
nymea-app/ui/images/powersocket.svg
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 96 96.000001"
|
||||
version="1.1"
|
||||
id="svg4874"
|
||||
height="96"
|
||||
width="96"
|
||||
sodipodi:docname="powersocket.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2792"
|
||||
inkscape:window-height="1698"
|
||||
id="namedview29"
|
||||
showgrid="false"
|
||||
inkscape:zoom="4.9166667"
|
||||
inkscape:cx="-46.727922"
|
||||
inkscape:cy="64.085507"
|
||||
inkscape:window-x="88"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4874">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid922" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs4876" />
|
||||
<metadata
|
||||
id="metadata4879">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<rect
|
||||
transform="rotate(90)"
|
||||
y="-95.999985"
|
||||
x="8.5593265e-06"
|
||||
height="96"
|
||||
width="96"
|
||||
id="rect4782"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:3.99920893;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
id="g4672"
|
||||
transform="matrix(0.69491525,0,0,0.69491525,14.644068,14.644068)">
|
||||
<path
|
||||
sodipodi:nodetypes="ssssssscccscccssscccscccss"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path833"
|
||||
d="M 48,6 C 24.82773,5.9999998 6,24.82773 6,48 6,71.17227 24.82773,90 48,90 71.17227,90 90,71.17227 90,48 90,24.82773 71.17227,6 48,6 Z m 0,4 c 10.505255,0 20.005255,4.247373 26.878941,11.121059 1.718422,1.718421 4.637502,5.622369 4.637502,5.622369 L 79.458236,44 c 0,0 2.541764,0 6.345835,0.110817 C 85.933635,45.389393 86,46.686843 86,48 c 0,1.313157 -0.06637,2.610607 -0.195929,3.889183 -3.383454,0.110817 -6.363812,-0.0712 -6.363812,-0.0712 l 0.07618,17.438585 c 0,0 -2.91908,3.903948 -4.637502,5.622369 C 68.005255,81.752627 58.505255,86 48,86 37.494745,86 27.994745,81.752627 21.121059,74.878941 19.402637,73.16052 16.483557,69.256572 16.483557,69.256572 l 0.0043,-17.492517 c 0,0 -2.487832,0.05541 -6.291903,0.125128 C 10.066365,50.610607 10,49.313157 10,48 c 0,-1.313157 0.06819,-2.721423 0.19775,-4 2.595072,0 4.042709,0 6.322237,0 -0.04759,-10.80225 -0.03643,-17.256572 -0.03643,-17.256572 0,0 2.91908,-3.903948 4.637502,-5.622369 C 27.994745,14.247372 37.494745,9.9999999 48,10 Z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
|
||||
<g
|
||||
transform="translate(0.32623959)"
|
||||
id="g965">
|
||||
<circle
|
||||
style="opacity:1;fill:#808080;fill-opacity:1;stroke:none;stroke-width:0.37795275;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path957"
|
||||
cx="30.419512"
|
||||
cy="48"
|
||||
r="5" />
|
||||
<circle
|
||||
r="5"
|
||||
cy="48"
|
||||
cx="64.928009"
|
||||
id="circle959"
|
||||
style="opacity:1;fill:#808080;fill-opacity:1;stroke:none;stroke-width:0.37795275;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
<rect
|
||||
y="11"
|
||||
x="45"
|
||||
height="10"
|
||||
width="6"
|
||||
id="rect961"
|
||||
style="opacity:1;fill:#808080;fill-opacity:1;stroke:none;stroke-width:0.37795275;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<rect
|
||||
style="opacity:1;fill:#808080;fill-opacity:1;stroke:none;stroke-width:0.37795275;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect967"
|
||||
width="6"
|
||||
height="10"
|
||||
x="45"
|
||||
y="75" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(67.857,-78.504997)"
|
||||
id="layer1">
|
||||
<rect
|
||||
x="78.504997"
|
||||
y="-28.143"
|
||||
width="96"
|
||||
height="96"
|
||||
transform="rotate(90)"
|
||||
style="color:#000000;fill:none"
|
||||
id="rect4782-7" />
|
||||
<path
|
||||
d="m -43.869,86.504 -0.01172,0.002 c -5.0328,0.05818 -8.7136,-0.12027 -11.725,1.541 -1.5055,0.83064 -2.6968,2.2356 -3.3555,3.9902 -0.65866,1.7547 -0.89648,3.8364 -0.89648,6.4668 v 56.002 c 0,2.6304 0.23782,4.7121 0.89648,6.4668 0.65866,1.7546 1.85,3.1596 3.3555,3.9902 3.011,1.6613 6.6918,1.4848 11.725,1.543 H -43.869 4.154 4.165719 c 5.0328,-0.0582 8.7136,0.11832 11.725,-1.543 1.5055,-0.83064 2.6968,-2.2356 3.3555,-3.9902 0.65866,-1.7547 0.89648,-3.8364 0.89648,-6.4668 V 98.504 c 0,-2.6304 -0.23782,-4.7121 -0.89648,-6.4668 -0.66,-1.759 -1.851,-3.163 -3.356,-3.994 -3.011,-1.661 -6.6922,-1.483 -11.725,-1.541 L 4.1535,86.5002 h -48.023 z m 0.01172,4 h 48 c 5.0383,0.05877 8.3519,0.23688 9.8164,1.0449 0.73364,0.40478 1.1527,0.85491 1.543,1.8945 0.39025,1.0396 0.64062,2.691 0.64062,5.0605 v 56.002 c 0,2.3696 -0.25037,4.0209 -0.64062,5.0606 -0.39025,1.0396 -0.80933,1.4898 -1.543,1.8945 -1.4645,0.80804 -4.7782,0.98616 -9.8164,1.0449 h -47.977 -0.02344 c -5.0383,-0.0588 -8.3519,-0.23688 -9.8164,-1.0449 -0.73364,-0.40478 -1.1508,-0.85491 -1.541,-1.8945 -0.39025,-1.0396 -0.64258,-2.691 -0.64258,-5.0606 v -56.002 c 0,-2.3696 0.25232,-4.0209 0.64258,-5.0605 0.39025,-1.0396 0.80738,-1.4898 1.541,-1.8945 1.4645,-0.80804 4.7782,-0.98616 9.8164,-1.0449 z"
|
||||
style="color:#000000;font-variant-ligatures:none;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;text-transform:none;white-space:normal;shape-padding:0;isolation:auto;mix-blend-mode:normal;solid-color:#000000;fill:#808080;color-rendering:auto;image-rendering:auto;shape-rendering:auto"
|
||||
id="path4643"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.3 KiB |
@ -43,6 +43,9 @@ MainPageTile {
|
||||
case "extendedShutter":
|
||||
page = "ShutterDeviceListPage.qml";
|
||||
break;
|
||||
case "powersocket":
|
||||
page = "PowerSocketsDeviceListPage.qml";
|
||||
break;
|
||||
default:
|
||||
page = "GenericDeviceListPage.qml"
|
||||
}
|
||||
@ -98,6 +101,7 @@ MainPageTile {
|
||||
case "extendedshutter":
|
||||
case "awning":
|
||||
case "extendedawning":
|
||||
case "powersocket":
|
||||
return buttonComponent
|
||||
default:
|
||||
console.warn("DevicesPageDelegate, inlineControl: Unhandled interface", model.name)
|
||||
@ -119,6 +123,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 +294,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 +313,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);
|
||||
|
||||
Reference in New Issue
Block a user