diff --git a/libnymea-app-core/devicemanager.cpp b/libnymea-app-core/devicemanager.cpp
index 3347f72f..35f3eb3c 100644
--- a/libnymea-app-core/devicemanager.cpp
+++ b/libnymea-app-core/devicemanager.cpp
@@ -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;
diff --git a/libnymea-common/types/device.cpp b/libnymea-common/types/device.cpp
index e130e629..2827a657 100644
--- a/libnymea-common/types/device.cpp
+++ b/libnymea-common/types/device.cpp
@@ -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;
+}
diff --git a/libnymea-common/types/device.h b/libnymea-common/types/device.h
index c5582fe3..bc7e59de 100644
--- a/libnymea-common/types/device.h
+++ b/libnymea-common/types/device.h
@@ -87,4 +87,6 @@ signals:
};
+QDebug operator<<(QDebug &dbg, Device* device);
+
#endif // DEVICE_H
diff --git a/nymea-app/images.qrc b/nymea-app/images.qrc
index 1bd386d1..bf1b791c 100644
--- a/nymea-app/images.qrc
+++ b/nymea-app/images.qrc
@@ -167,5 +167,6 @@
ui/images/media-playlist.svg
ui/images/stock_music.svg
ui/images/stock_video.svg
+ ui/images/sensors/presence.svg
diff --git a/nymea-app/resources.qrc b/nymea-app/resources.qrc
index 8961c881..01200294 100644
--- a/nymea-app/resources.qrc
+++ b/nymea-app/resources.qrc
@@ -144,5 +144,6 @@
ui/system/MqttBrokerSettingsPage.qml
ui/system/ServerConfigurationDialog.qml
ui/system/MqttPolicyPage.qml
+ ui/devicepages/BoolSensorDevicePage.qml
diff --git a/nymea-app/ui/Nymea.qml b/nymea-app/ui/Nymea.qml
index a6ad3c4c..2239f8e1 100644
--- a/nymea-app/ui/Nymea.qml
+++ b/nymea-app/ui/Nymea.qml
@@ -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",
diff --git a/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml b/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml
index edb6d39e..4f0d60d3 100644
--- a/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml
+++ b/nymea-app/ui/devicelistpages/SensorsDeviceListPage.qml
@@ -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)
diff --git a/nymea-app/ui/devicepages/BoolSensorDevicePage.qml b/nymea-app/ui/devicepages/BoolSensorDevicePage.qml
new file mode 100644
index 00000000..cf5fdb55
--- /dev/null
+++ b/nymea-app/ui/devicepages/BoolSensorDevicePage.qml
@@ -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
+ }
+ }
+
+
+
+ }
+}
+
diff --git a/nymea-app/ui/devicepages/SensorDevicePagePost110.qml b/nymea-app/ui/devicepages/SensorDevicePagePost110.qml
index cb8a6b39..1e27381e 100644
--- a/nymea-app/ui/devicepages/SensorDevicePagePost110.qml
+++ b/nymea-app/ui/devicepages/SensorDevicePagePost110.qml
@@ -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
}
}
}
diff --git a/nymea-app/ui/images/sensors/presence.svg b/nymea-app/ui/images/sensors/presence.svg
new file mode 100644
index 00000000..e0d06f0c
--- /dev/null
+++ b/nymea-app/ui/images/sensors/presence.svg
@@ -0,0 +1,163 @@
+
+
+
+