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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + +