implement presence and daylight sensor interface support
This commit is contained in:
parent
84d98ffc93
commit
dcccf71205
@ -242,6 +242,7 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap ¶ms)
|
||||
// qDebug() << "Set device state value:" << device->stateValue(stateTypeId) << value;
|
||||
}
|
||||
devices()->addDevice(device);
|
||||
qDebug() << "*** Added device:" << endl << device;
|
||||
}
|
||||
}
|
||||
m_fetchingData = false;
|
||||
|
||||
@ -134,3 +134,19 @@ void Device::setStateValue(const QUuid &stateTypeId, const QVariant &value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug &dbg, Device *device)
|
||||
{
|
||||
dbg.nospace() << "Device: " << device->name() << " (" << device->id().toString() << ") Class:" << device->deviceClass()->name() << " (" << device->deviceClassId().toString() << ")" << endl;
|
||||
for (int i = 0; i < device->params()->rowCount(); i++) {
|
||||
Param *p = device->params()->get(i);
|
||||
ParamType *pt = device->deviceClass()->paramTypes()->getParamType(p->paramTypeId());
|
||||
dbg << " Param " << i << ": " << pt->id().toString() << ": " << pt->name() << " = " << p->value() << endl;
|
||||
}
|
||||
for (int i = 0; i < device->deviceClass()->stateTypes()->rowCount(); i++) {
|
||||
StateType *st = device->deviceClass()->stateTypes()->get(i);
|
||||
State *s = device->states()->getState(st->id());
|
||||
dbg << " State " << i << ": " << st->id() << ": " << st->name() << " = " << s->value() << endl;
|
||||
}
|
||||
return dbg;
|
||||
}
|
||||
|
||||
@ -87,4 +87,6 @@ signals:
|
||||
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug &dbg, Device* device);
|
||||
|
||||
#endif // DEVICE_H
|
||||
|
||||
@ -167,5 +167,6 @@
|
||||
<file>ui/images/media-playlist.svg</file>
|
||||
<file>ui/images/stock_music.svg</file>
|
||||
<file>ui/images/stock_video.svg</file>
|
||||
<file>ui/images/sensors/presence.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -144,5 +144,6 @@
|
||||
<file>ui/system/MqttBrokerSettingsPage.qml</file>
|
||||
<file>ui/system/ServerConfigurationDialog.qml</file>
|
||||
<file>ui/system/MqttPolicyPage.qml</file>
|
||||
<file>ui/devicepages/BoolSensorDevicePage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@ -148,6 +148,10 @@ ApplicationWindow {
|
||||
return Qt.resolvedUrl("images/sensors/noise.svg");
|
||||
case "co2sensor":
|
||||
return Qt.resolvedUrl("images/sensors/co2.svg")
|
||||
case "daylightsensor":
|
||||
return Qt.resolvedUrl("images/sensors/light.svg")
|
||||
case "presencesensor":
|
||||
return Qt.resolvedUrl("images/sensors/presence.svg")
|
||||
case "media":
|
||||
case "mediacontroller":
|
||||
return Qt.resolvedUrl("images/mediaplayer-app-symbolic.svg")
|
||||
@ -216,6 +220,8 @@ ApplicationWindow {
|
||||
"pressuresensor": "grey",
|
||||
"noisesensor": "darkviolet",
|
||||
"co2sensor": "turquoise",
|
||||
"daylightsensor": "gold",
|
||||
"presencesensor": "darkblue",
|
||||
"smartmeterproducer": "lightgreen",
|
||||
"smartmeterconsumer": "orange",
|
||||
"extendedsmartmeterproducer": "blue",
|
||||
|
||||
@ -82,6 +82,8 @@ DeviceListPageBase {
|
||||
ListElement { interfaceName: "conductivitysensor"; stateName: "conductivity" }
|
||||
ListElement { interfaceName: "noisesensor"; stateName: "noise" }
|
||||
ListElement { interfaceName: "co2sensor"; stateName: "co2" }
|
||||
ListElement { interfaceName: "daylightsensor"; stateName: "daylight" }
|
||||
ListElement { interfaceName: "presencesensor"; stateName: "isPresent" }
|
||||
}
|
||||
|
||||
delegate: RowLayout {
|
||||
@ -89,8 +91,8 @@ DeviceListPageBase {
|
||||
visible: itemDelegate.deviceClass.interfaces.indexOf(model.interfaceName) >= 0
|
||||
Layout.preferredWidth: contentItem.width / dataGrid.columns
|
||||
|
||||
property var stateType: itemDelegate.deviceClass.stateTypes.findByName(model.stateName)
|
||||
property var stateValue: stateType ? itemDelegate.device.states.getState(stateType.id) : null
|
||||
property StateType stateType: itemDelegate.deviceClass.stateTypes.findByName(model.stateName)
|
||||
property State stateValue: stateType ? itemDelegate.device.states.getState(stateType.id) : null
|
||||
|
||||
ColorIcon {
|
||||
Layout.preferredHeight: app.iconSize * .8
|
||||
@ -102,17 +104,22 @@ DeviceListPageBase {
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: sensorValueDelegate.stateValue
|
||||
? "%1 %2".arg(Math.round(sensorValueDelegate.stateValue.value * 100) / 100).arg(sensorValueDelegate.stateType.unitString)
|
||||
: ""
|
||||
text: sensorValueDelegate.stateType && sensorValueDelegate.stateType.type.toLowerCase() === "bool"
|
||||
? sensorValueDelegate.stateType.displayName
|
||||
: sensorValueDelegate.stateValue
|
||||
? "%1 %2".arg(Math.round(sensorValueDelegate.stateValue.value * 100) / 100).arg(sensorValueDelegate.stateType.unitString)
|
||||
: ""
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: app.smallFont
|
||||
}
|
||||
Led {
|
||||
visible: sensorValueDelegate.stateType && sensorValueDelegate.stateType.type.toLowerCase() == "bool"
|
||||
on: visible && sensorValueDelegate.stateValue.value === true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
enterPage(index, false)
|
||||
|
||||
40
nymea-app/ui/devicepages/BoolSensorDevicePage.qml
Normal file
40
nymea-app/ui/devicepages/BoolSensorDevicePage.qml
Normal file
@ -0,0 +1,40 @@
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import Nymea 1.0
|
||||
import "../components"
|
||||
import "../customviews"
|
||||
|
||||
Item {
|
||||
|
||||
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
|
||||
|
||||
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins * 1.5
|
||||
name: root.powerState.value === true ? "../images/light-on.svg" : "../images/light-off.svg"
|
||||
color: root.powerState.value === true ? app.accentColor : keyColor
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,10 +6,12 @@ import "../components"
|
||||
import "../customviews"
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
anchors { fill: parent }
|
||||
interactive: contentHeight > height
|
||||
model: ListModel {
|
||||
Component.onCompleted: {
|
||||
var supportedInterfaces = ["temperaturesensor", "humiditysensor", "pressuresensor", "moisturesensor", "lightsensor", "conductivitysensor", "noisesensor", "co2sensor"]
|
||||
var supportedInterfaces = ["temperaturesensor", "humiditysensor", "pressuresensor", "moisturesensor", "lightsensor", "conductivitysensor", "noisesensor", "co2sensor", "presencesensor", "daylightsensor"]
|
||||
for (var i = 0; i < supportedInterfaces.length; i++) {
|
||||
print("checking", root.deviceClass.name, root.deviceClass.interfaces)
|
||||
if (root.deviceClass.interfaces.indexOf(supportedInterfaces[i]) >= 0) {
|
||||
@ -18,20 +20,107 @@ ListView {
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate: GenericTypeGraph {
|
||||
delegate: Loader {
|
||||
id: loader
|
||||
width: parent.width
|
||||
device: root.device
|
||||
stateType: root.deviceClass.stateTypes.findByName(stateTypeName)
|
||||
color: app.interfaceToColor(modelData)
|
||||
iconSource: app.interfaceToIcon(modelData)
|
||||
|
||||
implicitHeight: width * .6
|
||||
property string stateTypeName: {
|
||||
switch (modelData) {
|
||||
case "lightsensor":
|
||||
return "lightIntensity";
|
||||
default:
|
||||
return modelData.replace("sensor", "");
|
||||
property StateType stateType: root.deviceClass.stateTypes.findByName(interfaceStateMap[modelData])
|
||||
property string interfaceName: modelData
|
||||
|
||||
sourceComponent: stateType && stateType.type.toLowerCase() === "bool" ? boolComponent : graphComponent
|
||||
|
||||
property var interfaceStateMap: {
|
||||
"temperaturesensor": "temperature",
|
||||
"humiditysensor": "humidity",
|
||||
"pressuresensor": "pressure",
|
||||
"moisturesensor": "moisture",
|
||||
"lightsensor": "lightIntensity",
|
||||
"conductivitysensor": "conductivity",
|
||||
"noisesensor": "noise",
|
||||
"co2sensor": "co2",
|
||||
"presencesensor": "isPresent",
|
||||
"daylightsensor": "daylight"
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: graphComponent
|
||||
|
||||
GenericTypeGraph {
|
||||
device: root.device
|
||||
color: app.interfaceToColor(interfaceName)
|
||||
iconSource: app.interfaceToIcon(interfaceName)
|
||||
implicitHeight: width * .6
|
||||
property string interfaceName: parent.interfaceName
|
||||
stateType: parent.stateType
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: boolComponent
|
||||
GridLayout {
|
||||
id: boolView
|
||||
property string interfaceName: parent.interfaceName
|
||||
property StateType stateType: parent.stateType
|
||||
height: listView.height
|
||||
columns: app.landscape ? 2 : 1
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.rowSpan: 3
|
||||
ColorIcon {
|
||||
anchors.centerIn: parent
|
||||
height: app.iconSize * 4
|
||||
width: height
|
||||
name: app.interfaceToIcon(boolView.interfaceName)
|
||||
color: device.states.getState(boolView.stateType.id).value === true ? app.interfaceToColor(boolView.interfaceName) : keyColor
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: false
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
property StateType lastSeenStateType: root.deviceClass.stateTypes.findByName("lastSeenTime")
|
||||
property State lastSeenState: lastSeenStateType ? root.device.states.getState(lastSeenStateType.id) : null
|
||||
visible: lastSeenStateType !== null
|
||||
Label {
|
||||
text: qsTr("Last seen:")
|
||||
font.bold: true
|
||||
}
|
||||
Label {
|
||||
text: Qt.formatDateTime(new Date(parent.lastSeenState.value))
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: false
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
property StateType sunriseStateType: root.deviceClass.stateTypes.findByName("sunriseTime")
|
||||
property State sunriseState: sunriseStateType ? root.device.states.getState(sunriseStateType.id) : null
|
||||
visible: sunriseStateType !== null
|
||||
Label {
|
||||
text: qsTr("Sunrise:")
|
||||
font.bold: true
|
||||
}
|
||||
Label {
|
||||
text: parent.sunriseStateType ? Qt.formatDateTime(new Date(parent.sunriseState.value)) : ""
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: false
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
property StateType sunsetStateType: root.deviceClass.stateTypes.findByName("sunsetTime")
|
||||
property State sunsetState: sunsetStateType ? root.device.states.getState(sunsetStateType.id) : null
|
||||
visible: sunsetStateType !== null
|
||||
Label {
|
||||
text: qsTr("Sunset:")
|
||||
font.bold: true
|
||||
}
|
||||
Label {
|
||||
text: parent.sunsetStateType ? Qt.formatDateTime(new Date(parent.sunsetState.value)) : ""
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
163
nymea-app/ui/images/sensors/presence.svg
Normal file
163
nymea-app/ui/images/sensors/presence.svg
Normal file
@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<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"
|
||||
width="96"
|
||||
height="96"
|
||||
id="svg4874"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel r"
|
||||
viewBox="0 0 96 96.000001"
|
||||
sodipodi:docname="location.svg">
|
||||
<defs
|
||||
id="defs4876" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.7646075"
|
||||
inkscape:cx="42.448473"
|
||||
inkscape:cy="30.951139"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g4780"
|
||||
showgrid="false"
|
||||
showborder="true"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:bbox-paths="true"
|
||||
inkscape:bbox-nodes="true"
|
||||
inkscape:snap-bbox-edge-midpoints="true"
|
||||
inkscape:snap-bbox-midpoints="true"
|
||||
inkscape:object-paths="true"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:snap-object-midpoints="true"
|
||||
inkscape:snap-center="true"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5451"
|
||||
empspacing="8" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="8,-8.0000001"
|
||||
id="guide4063" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="4,-8.0000001"
|
||||
id="guide4065" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,88.000001"
|
||||
id="guide4067" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,92.000001"
|
||||
id="guide4069" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="104,4"
|
||||
id="guide4071" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,8.0000001"
|
||||
id="guide4073" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="92,-8.0000001"
|
||||
id="guide4075" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="88,-8.0000001"
|
||||
id="guide4077" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,84.000001"
|
||||
id="guide4074" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="12,-8.0000001"
|
||||
id="guide4076" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,12"
|
||||
id="guide4078" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="84,-9.0000001"
|
||||
id="guide4080" />
|
||||
<sodipodi:guide
|
||||
position="48,-8.0000001"
|
||||
orientation="1,0"
|
||||
id="guide4170" />
|
||||
<sodipodi:guide
|
||||
position="-8,48"
|
||||
orientation="0,1"
|
||||
id="guide4172" />
|
||||
</sodipodi:namedview>
|
||||
<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>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(67.857146,-78.50504)">
|
||||
<g
|
||||
transform="matrix(0,-1,-1,0,373.50506,516.50504)"
|
||||
id="g4845"
|
||||
style="display:inline">
|
||||
<g
|
||||
inkscape:export-ydpi="90"
|
||||
inkscape:export-xdpi="90"
|
||||
inkscape:export-filename="next01.png"
|
||||
transform="matrix(-0.9996045,0,0,1,575.94296,-611.00001)"
|
||||
id="g4778"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
transform="matrix(-1,0,0,1,575.99999,611)"
|
||||
id="g4780"
|
||||
style="display:inline">
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#808080;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.99940658;marker:none;enable-background:accumulate"
|
||||
d="M 48 0 A 25.999994 25.999998 0 0 0 22 26 A 25.999994 25.999998 0 0 0 23.650391 35.066406 A 25.999994 26.000001 0 0 1 23.210938 33.818359 C 27.972357 48.1029 37.544257 75.297989 47.998047 96 C 47.999047 95.999 47.99936 95.997093 48 95.996094 L 48.001953 96 C 58.455743 75.297988 68.027643 48.102901 72.789062 33.818359 A 25.999994 25.999998 0 0 0 74 26 A 25.999994 25.999998 0 0 0 48 0 z M 48 4 A 22.000006 22.000008 0 0 1 70 26 A 22.000006 22.000008 0 0 1 48 48 A 22.000006 22.000008 0 0 1 26 26 A 22.000006 22.000008 0 0 1 48 4 z "
|
||||
transform="matrix(0,-1,-1.0003957,0,438.00245,441.36222)"
|
||||
id="path4176" />
|
||||
<rect
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:none;stroke-width:4;marker:none;enable-background:accumulate"
|
||||
id="rect4782"
|
||||
width="96.037987"
|
||||
height="96"
|
||||
x="-438.00244"
|
||||
y="345.36221"
|
||||
transform="scale(-1,1)" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
Reference in New Issue
Block a user