moar work!
This commit is contained in:
parent
509ce837e4
commit
834c7a43c5
@ -83,7 +83,8 @@ void DeviceManager::addDevice(const QUuid &deviceClassId, const QString &name, c
|
||||
|
||||
void DeviceManager::notificationReceived(const QVariantMap &data)
|
||||
{
|
||||
if (data.value("notification").toString() == "Devices.StateChanged") {
|
||||
QString notification = data.value("notification").toString();
|
||||
if (notification == "Devices.StateChanged") {
|
||||
qDebug() << "Device state changed" << data.value("params");
|
||||
Device *dev = m_devices->getDevice(data.value("params").toMap().value("deviceId").toUuid());
|
||||
if (!dev) {
|
||||
@ -91,20 +92,33 @@ void DeviceManager::notificationReceived(const QVariantMap &data)
|
||||
return;
|
||||
}
|
||||
dev->setStateValue(data.value("params").toMap().value("stateTypeId").toUuid(), data.value("params").toMap().value("value"));
|
||||
} else if (notification == "Devices.DeviceAdded") {
|
||||
Device *dev = JsonTypes::unpackDevice(data.value("params").toMap().value("device").toMap(), m_devices);
|
||||
if (!dev) {
|
||||
qWarning() << "Cannot parse json device:" << data;
|
||||
return;
|
||||
}
|
||||
m_devices->addDevice(dev);
|
||||
} else if (notification == "Devices.DeviceRemoved") {
|
||||
QUuid deviceId = data.value("params").toMap().value("deviceId").toUuid();
|
||||
qDebug() << "JsonRpc: Notification: Device removed" << deviceId.toString();
|
||||
Device *device = m_devices->getDevice(deviceId);
|
||||
m_devices->removeDevice(device);
|
||||
device->deleteLater();
|
||||
} else {
|
||||
qWarning() << "DeviceManager unhandled device notification received" << data;
|
||||
qWarning() << "DeviceManager unhandled device notification received" << notification;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::getVendorsResponse(const QVariantMap ¶ms)
|
||||
{
|
||||
qDebug() << "Got GetSupportedVendors response" << params;
|
||||
// qDebug() << "Got GetSupportedVendors response" << params;
|
||||
if (params.value("params").toMap().keys().contains("vendors")) {
|
||||
QVariantList vendorList = params.value("params").toMap().value("vendors").toList();
|
||||
foreach (QVariant vendorVariant, vendorList) {
|
||||
Vendor *vendor = JsonTypes::unpackVendor(vendorVariant.toMap(), Engine::instance()->deviceManager()->vendors());
|
||||
m_vendors->addVendor(vendor);
|
||||
qDebug() << "Added Vendor:" << vendor->name();
|
||||
// qDebug() << "Added Vendor:" << vendor->name();
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,6 +180,10 @@ void DeviceManager::getConfiguredDevicesResponse(const QVariantMap ¶ms)
|
||||
QVariant value = stateMap.toMap().value("value");
|
||||
if (st->type() == "Bool") {
|
||||
value.convert(QVariant::Bool);
|
||||
} else if (st->type() == "Double") {
|
||||
value.convert(QVariant::Double);
|
||||
} else if (st->type() == "Int") {
|
||||
value.convert(QVariant::Int);
|
||||
}
|
||||
device->setStateValue(stateTypeId, value);
|
||||
}
|
||||
@ -189,11 +207,8 @@ void DeviceManager::addDeviceResponse(const QVariantMap ¶ms)
|
||||
|
||||
void DeviceManager::removeDeviceResponse(const QVariantMap ¶ms)
|
||||
{
|
||||
QUuid deviceId = params.value("params").toMap().value("deviceId").toUuid();
|
||||
qDebug() << "JsonRpc: Notification: Device removed" << deviceId.toString();
|
||||
Device *device = m_devices->getDevice(deviceId);
|
||||
m_devices->removeDevice(device);
|
||||
device->deleteLater();
|
||||
qDebug() << "Device removed response" << params;
|
||||
emit removeDeviceReply(params.value("params").toMap());
|
||||
}
|
||||
|
||||
void DeviceManager::pairDeviceResponse(const QVariantMap ¶ms)
|
||||
|
||||
@ -73,6 +73,7 @@ signals:
|
||||
void pairDeviceReply(const QVariantMap ¶ms);
|
||||
void confirmPairingReply(const QVariantMap ¶ms);
|
||||
void addDeviceReply(const QVariantMap ¶ms);
|
||||
void removeDeviceReply(const QVariantMap ¶ms);
|
||||
|
||||
private:
|
||||
Vendors *m_vendors;
|
||||
|
||||
@ -109,7 +109,7 @@ DeviceClass *JsonTypes::unpackDeviceClass(const QVariantMap &deviceClassMap, QOb
|
||||
|
||||
Param *JsonTypes::unpackParam(const QVariantMap ¶mMap, QObject *parent)
|
||||
{
|
||||
return new Param(paramMap.value("name").toString(), paramMap.value("value"), parent);
|
||||
return new Param(paramMap.value("paramTypeId").toString(), paramMap.value("value"), parent);
|
||||
}
|
||||
|
||||
ParamType *JsonTypes::unpackParamType(const QVariantMap ¶mTypeMap, QObject *parent)
|
||||
@ -117,6 +117,7 @@ ParamType *JsonTypes::unpackParamType(const QVariantMap ¶mTypeMap, QObject *
|
||||
ParamType *paramType = new ParamType(parent);
|
||||
paramType->setId(paramTypeMap.value("id").toString());
|
||||
paramType->setName(paramTypeMap.value("name").toString());
|
||||
paramType->setDisplayName(paramTypeMap.value("displayName").toString());
|
||||
paramType->setType(paramTypeMap.value("type").toString());
|
||||
paramType->setIndex(paramTypeMap.value("index").toInt());
|
||||
paramType->setDefaultValue(paramTypeMap.value("defaultValue"));
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
* *
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QtQml/QQmlContext>
|
||||
#include <QQmlApplicationEngine>
|
||||
@ -46,7 +46,7 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
QGuiApplication application(argc, argv);
|
||||
QApplication application(argc, argv);
|
||||
application.setApplicationName("guh-control");
|
||||
application.setOrganizationName("guh");
|
||||
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
|
||||
ValueLogsProxyModel::ValueLogsProxyModel(QObject *parent) : LogsModel(parent)
|
||||
{
|
||||
|
||||
m_minimumValue = QVariant(0);
|
||||
m_maximumValue = QVariant(0);
|
||||
}
|
||||
|
||||
void ValueLogsProxyModel::update()
|
||||
@ -40,8 +41,6 @@ QVariant ValueLogsProxyModel::maximumValue() const
|
||||
|
||||
void ValueLogsProxyModel::logsReply(const QVariantMap &data)
|
||||
{
|
||||
m_busy = false;
|
||||
emit busyChanged();
|
||||
|
||||
qDebug() << "logs reply";
|
||||
|
||||
@ -84,7 +83,9 @@ void ValueLogsProxyModel::logsReply(const QVariantMap &data)
|
||||
continue;
|
||||
}
|
||||
QList<QVariant> tmp = entries[slot];
|
||||
tmp.append(entryMap.value("value"));
|
||||
QVariant value = entryMap.value("value");
|
||||
value.convert(QVariant::Double);
|
||||
tmp.append(value);
|
||||
entries[slot] = tmp;
|
||||
// qDebug() << "adding value to slot" << slot << entryMap.value("value") << QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
|
||||
}
|
||||
@ -114,15 +115,16 @@ void ValueLogsProxyModel::logsReply(const QVariantMap &data)
|
||||
continue;
|
||||
}
|
||||
LogEntry *entry = new LogEntry(startTime().addSecs(stepSize * i).addSecs(stepSize * .5), avg, this);
|
||||
// qDebug() << "filling slot" << i << "average:" << avg << entry->timestamp();
|
||||
m_list.append(entry);
|
||||
|
||||
// qDebug() << "**" << m_minimumValue << entry->value();
|
||||
if (m_minimumValue.isNull() || entry->value() < m_minimumValue) {
|
||||
m_minimumValue = qRound(entry->value().toDouble());
|
||||
}
|
||||
if (m_maximumValue.isNull() || entry->value() > m_maximumValue) {
|
||||
m_maximumValue = qRound(entry->value().toDouble());
|
||||
}
|
||||
qDebug() << "filling slot" << i << "average:" << avg << entry->timestamp().toString() << "min:" << m_minimumValue << "max:" << m_maximumValue;
|
||||
|
||||
}
|
||||
|
||||
@ -133,4 +135,7 @@ void ValueLogsProxyModel::logsReply(const QVariantMap &data)
|
||||
emit countChanged();
|
||||
qDebug() << "min" << minimumValue() << "max" << maximumValue();
|
||||
|
||||
m_busy = false;
|
||||
emit busyChanged();
|
||||
|
||||
}
|
||||
|
||||
@ -101,5 +101,11 @@
|
||||
<file>ui/images/battery/battery-090.svg</file>
|
||||
<file>ui/images/battery/battery-100.svg</file>
|
||||
<file>ui/images/dialog-warning-symbolic.svg</file>
|
||||
<file>ui/images/magic.svg</file>
|
||||
<file>ui/EditDevicesPage.qml</file>
|
||||
<file>ui/devicepages/ConfigureThingPage.qml</file>
|
||||
<file>ui/magic/DeviceRulesPage.qml</file>
|
||||
<file>ui/magic/SelectEventPage.qml</file>
|
||||
<file>ui/magic/NewThingMagicPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
38
guh-control/ui/EditDevicesPage.qml
Normal file
38
guh-control/ui/EditDevicesPage.qml
Normal file
@ -0,0 +1,38 @@
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import "components"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
header: GuhHeader {
|
||||
text: "Configure Things"
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: Engine.deviceManager.devices
|
||||
delegate: ItemDelegate {
|
||||
width: parent.width
|
||||
contentItem: RowLayout {
|
||||
spacing: app.margins
|
||||
ColorIcon {
|
||||
height: app.iconSize
|
||||
width: height
|
||||
name: app.interfaceToIcon(model.interfaces[0])
|
||||
color: app.guhAccent
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: model.name
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("devicepages/ConfigureThingPage.qml"), {device: Engine.deviceManager.devices.get(index)})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,10 +7,10 @@ Page {
|
||||
id: root
|
||||
header: GuhHeader {
|
||||
text: "Magic"
|
||||
backButtonVisible: false
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "images/add.svg"
|
||||
imageSource: Qt.resolvedUrl("images/add.svg")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("magic/NewRulePage.qml"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,17 +21,26 @@ Page {
|
||||
IconMenuItem {
|
||||
iconSource: "../images/share.svg"
|
||||
text: "Configure things"
|
||||
onTriggered: pageStack.push(Qt.resolvedUrl("EditDevicesPage.qml"))
|
||||
}
|
||||
IconMenuItem {
|
||||
iconSource: "../images/add.svg"
|
||||
text: "Add a new thing..."
|
||||
text: "Add a new thing"
|
||||
onTriggered: pageStack.push(Qt.resolvedUrl("NewDeviceWizard.qml"))
|
||||
}
|
||||
MenuSeparator {}
|
||||
IconMenuItem {
|
||||
iconSource: "../images/magic.svg"
|
||||
text: "Magic"
|
||||
onTriggered: pageStack.push(Qt.resolvedUrl("MagicPage.qml"))
|
||||
}
|
||||
MenuSeparator {}
|
||||
IconMenuItem {
|
||||
iconSource: "../images/settings.svg"
|
||||
text: "App settings"
|
||||
onTriggered: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
|
||||
}
|
||||
MenuSeparator {}
|
||||
IconMenuItem {
|
||||
iconSource: "../images/info.svg"
|
||||
text: "System information"
|
||||
|
||||
@ -16,7 +16,7 @@ Page {
|
||||
}
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "images/close.svg"
|
||||
imageSource: "../images/close.svg"
|
||||
onClicked: pageStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ ToolBar {
|
||||
Layout.fillHeight: true
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: app.largeFont
|
||||
elide: Text.ElideRight
|
||||
color: "#333"
|
||||
text: root.text.toUpperCase()
|
||||
}
|
||||
|
||||
@ -2,17 +2,16 @@ import QtQuick 2.5
|
||||
import QtQuick.Controls 2.1
|
||||
|
||||
ToolButton {
|
||||
property alias imageSource: image.source
|
||||
property alias imageSource: image.name
|
||||
property alias color: image.color
|
||||
|
||||
contentItem: Item {
|
||||
height: 20
|
||||
width: 20
|
||||
Image {
|
||||
ColorIcon {
|
||||
id: image
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins / 2
|
||||
sourceSize.height: height
|
||||
sourceSize.width: width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Controls.Material 2.1
|
||||
import QtQuick.Layouts 1.3
|
||||
//import QtCharts 2.1
|
||||
import "../components"
|
||||
import Guh 1.0
|
||||
|
||||
@ -22,11 +24,25 @@ CustomViewBase {
|
||||
Component.onCompleted: updateTimer.start();
|
||||
onAverageChanged: updateTimer.start()
|
||||
onStartTimeChanged: updateTimer.start();
|
||||
|
||||
onBusyChanged: {
|
||||
if (!busy) {
|
||||
|
||||
// lineSeries1.clear()
|
||||
// splineSeries.clear()
|
||||
// print("---", axisX.min, axisX.max)
|
||||
// for (var i = 0; i < logsModel.count; i++) {
|
||||
// print("adding", logsModel.get(i).timestamp, logsModel.get(i).value)
|
||||
// lineSeries1.append(logsModel.get(i).timestamp, logsModel.get(i).value)
|
||||
// splineSeries.append(logsModel.get(i).timestamp, logsModel.get(i).value)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: updateTimer
|
||||
interval: 0
|
||||
interval: 10
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
print("updating:", logsModel.startTime)
|
||||
@ -91,5 +107,70 @@ CustomViewBase {
|
||||
model: logsModel
|
||||
color: app.interfaceToColor(root.interfaceName)
|
||||
}
|
||||
|
||||
// ChartView {
|
||||
// id: chartView
|
||||
// Layout.fillWidth: true
|
||||
// Layout.preferredHeight: 300
|
||||
// animationOptions: ChartView.SeriesAnimations
|
||||
// theme: ChartView.ChartThemeQt
|
||||
// backgroundColor: Material.background
|
||||
// property bool openGL: false
|
||||
// property bool openGLSupported: true
|
||||
// onOpenGLChanged: {
|
||||
// if (openGLSupported) {
|
||||
// series("signal 1").useOpenGL = openGL;
|
||||
// series("signal 2").useOpenGL = openGL;
|
||||
// }
|
||||
// }
|
||||
// Component.onCompleted: {
|
||||
// if (!series("signal 1").useOpenGL) {
|
||||
// openGLSupported = false
|
||||
// openGL = false
|
||||
// }
|
||||
// }
|
||||
|
||||
// ValueAxis {
|
||||
// id: axisY1
|
||||
// min: logsModel.minimumValue - 1
|
||||
// max: logsModel.maximumValue + 1
|
||||
// }
|
||||
|
||||
// DateTimeAxis {
|
||||
// id: axisX
|
||||
// min: logsModel.startTime
|
||||
// max: logsModel.endTime
|
||||
// format: {
|
||||
// switch (logsModel.average) {
|
||||
// case ValueLogsProxyModel.AverageMinute:
|
||||
// case ValueLogsProxyModel.AverageHourly:
|
||||
// case ValueLogsProxyModel.AverageQuarterHour:
|
||||
// return "hh:mm"
|
||||
// }
|
||||
// return "ddd<br> dd.MM.<br>hh:mm"
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// AreaSeries {
|
||||
// axisX: axisX
|
||||
// axisY: axisY1
|
||||
// borderWidth: 0
|
||||
// name: app.interfaceToString(interfaceName)
|
||||
// borderColor: app.interfaceToColor(interfaceName)
|
||||
// color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, .4)
|
||||
// useOpenGL: chartView.openGL
|
||||
// upperSeries: LineSeries {
|
||||
// id: lineSeries1
|
||||
// }
|
||||
// }
|
||||
// SplineSeries {
|
||||
// id: splineSeries
|
||||
// axisX: axisX
|
||||
// axisY: axisY1
|
||||
// width: 3
|
||||
// color: app.interfaceToColor(interfaceName)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,9 +100,7 @@ Page {
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (deviceClass.interfaces.indexOf("colorlight") >= 0) {
|
||||
pageStack.push(Qt.resolvedUrl("../devicepages/ColorLightDevicePage.qml"), {device: devicesProxy.get(index)})
|
||||
}
|
||||
pageStack.push(Qt.resolvedUrl("../devicepages/ColorLightDevicePage.qml"), {device: devicesProxy.get(index)})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,21 +5,8 @@ import Guh 1.0
|
||||
import "../components"
|
||||
import "../actiondelegates"
|
||||
|
||||
Page {
|
||||
DevicePageBase {
|
||||
id: root
|
||||
property var device: null
|
||||
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
|
||||
|
||||
header: GuhHeader {
|
||||
text: device.name
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/info.svg"
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("GenericDeviceStateDetailsPage.qml"), {device: root.device})
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
@ -96,8 +83,9 @@ Page {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
property var actionType: root.deviceClass.actionTypes.findByName("colorTemperature")
|
||||
property var ctState: root.device.states.getState(actionType.id)
|
||||
ct: ctState.value
|
||||
property var ctState: actionType ? root.device.states.getState(actionType.id) : null
|
||||
ct: ctState ? ctState.value : 0
|
||||
visible: root.deviceClass.interfaces.indexOf("colorlight") >= 0
|
||||
|
||||
height: 80
|
||||
|
||||
@ -132,13 +120,19 @@ Page {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
actionType: root.deviceClass.actionTypes.findByName("color")
|
||||
actionState: root.device.states.getState(actionType.id).value
|
||||
actionState: actionType ? root.device.states.getState(actionType.id).value : null
|
||||
visible: root.deviceClass.interfaces.indexOf("colorlight") >= 0
|
||||
|
||||
onExecuteAction: {
|
||||
Engine.deviceManager.executeAction(root.device.id, actionType.id, params)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
53
guh-control/ui/devicepages/ConfigureThingPage.qml
Normal file
53
guh-control/ui/devicepages/ConfigureThingPage.qml
Normal file
@ -0,0 +1,53 @@
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import Guh 1.0
|
||||
import "../components"
|
||||
|
||||
Page {
|
||||
id: root
|
||||
property var device: null
|
||||
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
|
||||
header: GuhHeader {
|
||||
text: root.device.name
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/delete.svg"
|
||||
color: "red"
|
||||
onClicked: {
|
||||
Engine.deviceManager.removeDevice(root.device.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Engine.deviceManager
|
||||
onRemoveDeviceReply: {
|
||||
if (params.deviceError === "DeviceErrorNoError") {
|
||||
pageStack.pop();
|
||||
return;
|
||||
}
|
||||
print("Remove device error!", params)
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: root.device.params
|
||||
delegate: ItemDelegate {
|
||||
width: parent.width
|
||||
contentItem: RowLayout {
|
||||
Label {
|
||||
text: root.deviceClass.paramTypes.getParamType(model.id).displayName
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: model.value
|
||||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,21 @@ Page {
|
||||
|
||||
default property alias data: contentItem.data
|
||||
|
||||
header: GuhHeader {
|
||||
text: device.name
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/magic.svg"
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("../magic/DeviceRulesPage.qml"), {device: root.device})
|
||||
}
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/info.svg"
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("GenericDeviceStateDetailsPage.qml"), {device: root.device})
|
||||
}
|
||||
}
|
||||
|
||||
Pane {
|
||||
id: infoPane
|
||||
visible: batteryState !== null || (connectedState !== null && connectedState.value === false)
|
||||
|
||||
@ -7,16 +7,6 @@ import "../components"
|
||||
DevicePageBase {
|
||||
id: root
|
||||
|
||||
header: GuhHeader {
|
||||
text: device.name
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/info.svg"
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("GenericDeviceStateDetailsPage.qml"), {device: root.device})
|
||||
}
|
||||
}
|
||||
|
||||
Flickable {
|
||||
id: flickable
|
||||
anchors.fill: parent
|
||||
|
||||
@ -5,26 +5,33 @@ import Guh 1.0
|
||||
import "../components"
|
||||
import "../customviews"
|
||||
|
||||
Page {
|
||||
DevicePageBase {
|
||||
id: root
|
||||
property var device: null
|
||||
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
|
||||
|
||||
header: GuhHeader {
|
||||
text: device.name
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/info.svg"
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("GenericDeviceStateDetailsPage.qml"), {device: root.device})
|
||||
Flickable {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
contentHeight: content.implicitHeight
|
||||
ColumnLayout {
|
||||
id: content
|
||||
width: parent.width
|
||||
WeatherView {
|
||||
Layout.fillWidth: true
|
||||
device: root.device
|
||||
deviceClass: root.deviceClass
|
||||
}
|
||||
SensorView {
|
||||
Layout.fillWidth: true
|
||||
device: root.device
|
||||
deviceClass: root.deviceClass
|
||||
interfaceName: "temperaturesensor"
|
||||
}
|
||||
SensorView {
|
||||
Layout.fillWidth: true
|
||||
device: root.device
|
||||
deviceClass: root.deviceClass
|
||||
interfaceName: "humiditysensor"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WeatherView {
|
||||
anchors.fill: parent
|
||||
device: root.device
|
||||
deviceClass: root.deviceClass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
296
guh-control/ui/images/magic.svg
Normal file
296
guh-control/ui/images/magic.svg
Normal file
@ -0,0 +1,296 @@
|
||||
<?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.92.2 (5c3e80d, 2017-08-06)"
|
||||
viewBox="0 0 96 96.000001"
|
||||
sodipodi:docname="magic.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.6568543"
|
||||
inkscape:cx="115.91572"
|
||||
inkscape:cy="46.722217"
|
||||
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:snap-global="true"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1698"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="44"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid5451"
|
||||
empspacing="8" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="8,-8.0000001"
|
||||
id="guide4063"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="4,-8.0000001"
|
||||
id="guide4065"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,88.000001"
|
||||
id="guide4067"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,92.000001"
|
||||
id="guide4069"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="104,4"
|
||||
id="guide4071"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,8.0000001"
|
||||
id="guide4073"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="92,-8.0000001"
|
||||
id="guide4075"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="88,-8.0000001"
|
||||
id="guide4077"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-8,84.000001"
|
||||
id="guide4074"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="12,-8.0000001"
|
||||
id="guide4076"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="0,1"
|
||||
position="-5,12"
|
||||
id="guide4078"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
orientation="1,0"
|
||||
position="84,-9.0000001"
|
||||
id="guide4080"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="48,-8.0000001"
|
||||
orientation="1,0"
|
||||
id="guide4170"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="-8,48"
|
||||
orientation="0,1"
|
||||
id="guide4172"
|
||||
inkscape:locked="false" />
|
||||
</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">
|
||||
<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
|
||||
id="g1894"
|
||||
transform="matrix(0.8660254,0.49980225,-0.50019783,0.8660254,249.00681,-142.21407)">
|
||||
<rect
|
||||
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:3.00153852;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1888"
|
||||
width="12"
|
||||
height="88.034821"
|
||||
x="-399.36221"
|
||||
y="-434.00089"
|
||||
transform="matrix(0,-1,-1,0,0,0)"
|
||||
rx="3"
|
||||
ry="3.0011871" />
|
||||
<rect
|
||||
style="fill:#808080;fill-opacity:1;stroke:none;stroke-width:3.00153852;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1890"
|
||||
width="12"
|
||||
height="60.023739"
|
||||
x="-399.36221"
|
||||
y="-419.99533"
|
||||
transform="matrix(0,-1,-1,0,0,0)" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#808080;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1903"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="12"
|
||||
sodipodi:cy="63.807842"
|
||||
sodipodi:r1="11.632512"
|
||||
sodipodi:r2="5.8162556"
|
||||
sodipodi:arg1="1.3326172"
|
||||
sodipodi:arg2="1.9609357"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 14.7445,75.111959 -4.9565227,-5.924918 -7.6907342,0.72414 4.1032818,-6.544833 -3.0652651,-7.090552 7.4924902,1.879988 5.796296,-5.106341 0.527332,7.70673 6.647573,3.934659 -7.166581,2.883033 z"
|
||||
transform="matrix(0,-1,-1.0003957,0,433.33151,433.80227)"
|
||||
inkscape:transform-center-x="-0.84809303"
|
||||
inkscape:transform-center-y="0.27286362" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#808080;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1905"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="14.86737"
|
||||
sodipodi:cy="34.318844"
|
||||
sodipodi:r1="6.986371"
|
||||
sodipodi:r2="3.4931855"
|
||||
sodipodi:arg1="0.97303794"
|
||||
sodipodi:arg2="1.6013565"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 18.799236,40.093773 -4.038602,-2.283375 -4.170535,2.032424 0.923622,-4.54654 -3.2217163,-3.338361 4.6094313,-0.526542 2.179405,-4.095644 1.925164,4.22112 4.568662,0.807113 -3.419615,3.135337 z"
|
||||
transform="matrix(0,-1,-1.0003957,0,435.29822,435.88751)"
|
||||
inkscape:transform-center-x="-0.065962241"
|
||||
inkscape:transform-center-y="-0.6040865" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#808080;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1907"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="69.667763"
|
||||
sodipodi:cy="48"
|
||||
sodipodi:r1="7.9908891"
|
||||
sodipodi:r2="3.9954443"
|
||||
sodipodi:arg1="0.86871607"
|
||||
sodipodi:arg2="1.4970346"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 74.828338,54.101047 -4.866132,-2.116467 -4.502178,2.808746 0.509162,-5.28199 -4.062526,-3.413877 5.180811,-1.147982 1.9914,-4.918638 2.692755,4.572498 5.293279,0.373992 -3.516597,3.973941 z"
|
||||
transform="matrix(0,-1,-1.0003957,0,423.1292,432.66883)"
|
||||
inkscape:transform-center-x="0.18198021"
|
||||
inkscape:transform-center-y="-0.58791341" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#808080;fill-opacity:1;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1909"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="8"
|
||||
sodipodi:cy="11.999999"
|
||||
sodipodi:r1="7.0902119"
|
||||
sodipodi:r2="3.5451059"
|
||||
sodipodi:arg1="0.97138318"
|
||||
sodipodi:arg2="1.5997017"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="M 12,17.854152 7.8975417,15.543624 3.6684378,17.613258 4.598151,12.997596 1.3229474,9.6150309 6,9.0729227 8.2049168,4.912749 l 1.9608642,4.2806207 4.637917,0.8114363 -3.465172,3.187677 z"
|
||||
transform="matrix(0,-1,-1.0003957,0,435.19471,439.528)"
|
||||
inkscape:transform-center-x="-0.06331877"
|
||||
inkscape:transform-center-y="-0.61654618" />
|
||||
<path
|
||||
style="fill:#808080;fill-opacity:1;stroke:#ffffff;stroke-width:1.50029671;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 422.9456,387.13916 c 0.41673,-4.36096 0.4085,-8.39102 -4.7e-4,-11.88327 -0.81794,-6.98452 -3.23883,-11.8178 -7.06881,-12.84455 -7.66091,-2.05289 -18.05798,11.90079 -23.22212,31.16593 -5.16409,19.26514 -3.45309,39.40357 4.30075,41.07181 5.99681,1.29022 17.70837,-11.65794 19.05693,-14.99875 -0.63403,1.52511 -1.7672,5.36696 -5.55437,10.31771 -5.48611,7.17168 -11.19038,11.06022 -16.10785,9.74286 -9.83518,-2.63379 -12.43389,-24.81834 -5.80431,-49.55007 6.62937,-24.73177 19.97658,-42.64531 29.81151,-40.0106 4.91759,1.31689 8.02607,7.52147 9.07645,16.4883 0.52519,4.48341 0.53585,9.65739 8.7e-4,15.25624 -0.26749,2.79943 -0.67139,5.70507 -1.21559,8.68373"
|
||||
id="path1945"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccscscccssc" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#808080;fill-opacity:1;stroke:#ffffff;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1970"
|
||||
sodipodi:sides="5"
|
||||
sodipodi:cx="46.3125"
|
||||
sodipodi:cy="5.5"
|
||||
sodipodi:r1="13.101168"
|
||||
sodipodi:r2="6.5505843"
|
||||
sodipodi:arg1="0.51914607"
|
||||
sodipodi:arg2="1.1474646"
|
||||
inkscape:flatsided="false"
|
||||
inkscape:rounded="0"
|
||||
inkscape:randomized="0"
|
||||
d="m 57.687499,11.999999 -8.684017,-0.527665 -5.35778,6.854543 -2.18167,-8.4220481 -8.174703,-2.9773817 7.335671,-4.6774469 0.305536,-8.6946667 6.715363,5.53122727 8.363535,-2.39621797 -3.185348,8.0959334 z"
|
||||
transform="matrix(0,-1,-1.0003957,0,430.32036,431.20152)"
|
||||
inkscape:transform-center-x="0.82409001"
|
||||
inkscape:transform-center-y="0.44110773" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
75
guh-control/ui/magic/DeviceRulesPage.qml
Normal file
75
guh-control/ui/magic/DeviceRulesPage.qml
Normal file
@ -0,0 +1,75 @@
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import "../components"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
|
||||
property var device: null
|
||||
|
||||
header: GuhHeader {
|
||||
text: qsTr("Magic involving %1").arg(root.device.name)
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/add.svg"
|
||||
visible: rulesListView.count > 0
|
||||
onClicked: addRule()
|
||||
}
|
||||
}
|
||||
|
||||
function addRule() {
|
||||
pageStack.push(Qt.resolvedUrl("NewThingMagicPage.qml"), {device: root.device, text: "Add magic"})
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: rulesListView
|
||||
anchors.fill: parent
|
||||
|
||||
model: RulesFilterModel {
|
||||
id: rulesFilterModel
|
||||
rules: Engine.ruleManager.rules
|
||||
filterEventDeviceId: root.device.id
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
text: model.name
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - app.margins * 2
|
||||
spacing: app.margins * 2
|
||||
visible: rulesListView.count == 0
|
||||
|
||||
Label {
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("There's no magic involving %1.").arg(root.device.name)
|
||||
font.pixelSize: app.largeFont
|
||||
}
|
||||
Label {
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("Add some using the wizard stick!")
|
||||
font.pixelSize: app.largeFont
|
||||
}
|
||||
|
||||
AbstractButton {
|
||||
height: app.iconSize * 4
|
||||
width: height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
name: "../images/magic.svg"
|
||||
}
|
||||
|
||||
onClicked: addRule()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,9 @@ import "../components"
|
||||
|
||||
Page {
|
||||
id: root
|
||||
|
||||
property var device: null
|
||||
|
||||
header: GuhHeader {
|
||||
text: "New rule"
|
||||
onBackPressed: pageStack.pop()
|
||||
|
||||
75
guh-control/ui/magic/NewThingMagicPage.qml
Normal file
75
guh-control/ui/magic/NewThingMagicPage.qml
Normal file
@ -0,0 +1,75 @@
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 2.1
|
||||
import "../components"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
property alias text: header.text
|
||||
property var device: null
|
||||
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
|
||||
header: GuhHeader {
|
||||
id: header
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: eventModel
|
||||
ListElement { interfaceName: "temperaturesensor"; text: "When it's freezing..."; identifier: "freeze"}
|
||||
ListElement { interfaceName: "battery"; text: "When the device runs out of battery..."; identifier: "lowBattery"}
|
||||
ListElement { interfaceName: "weather"; text: "When it starts raining..."; identifier: "rain" }
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: actionModel
|
||||
ListElement { interfaceName: "light"; text: "Switch light when..."; identifier: "switchLight"}
|
||||
ListElement { interfaceName: "dimmablelight"; text: "Dim light when..."; identifier: "dimLight"}
|
||||
ListElement { interfaceName: "colorlight"; text: "Set light color when..."; identifier: "colorLight" }
|
||||
ListElement { interfaceName: "mediacontroller"; text: "Pause playback when..."; identifier: "pausePlayback" }
|
||||
ListElement { interfaceName: "mediacontroller"; text: "Resume playback when..."; identifier: "resumePlayback" }
|
||||
ListElement { interfaceName: "extendedvolumecontroller"; text: "Set volume..."; identifier: "setVolume" }
|
||||
ListElement { interfaceName: "extendedvolumecontroller"; text: "Mute when..."; identifier: "mute" }
|
||||
ListElement { interfaceName: "extendedvolumecontroller"; text: "Unmute when..."; identifier: "unmute" }
|
||||
ListElement { interfaceName: "notifications"; text: "Notify me when..."; identifier: "notify" }
|
||||
}
|
||||
|
||||
function entrySelected(identifier) {
|
||||
switch (identifier) {
|
||||
case "freeze":
|
||||
pageStack.push(Qt.resolvedUrl("SelectActionPage.qml"), {device: root.device })
|
||||
}
|
||||
}
|
||||
|
||||
onDeviceClassChanged: {
|
||||
actualModel.clear()
|
||||
print("device supports interfaces", deviceClass.interfaces)
|
||||
for (var i = 0; i < eventModel.count; i++) {
|
||||
print("event is for interface", eventModel.get(i).interfaceName)
|
||||
if (deviceClass.interfaces.indexOf(eventModel.get(i).interfaceName) >= 0) {
|
||||
actualModel.append(eventModel.get(i))
|
||||
}
|
||||
}
|
||||
print("huh")
|
||||
for (var i = 0; i < actionModel.count; i++) {
|
||||
print("action is for interface", actionModel.get(i).interfaceName)
|
||||
if (deviceClass.interfaces.indexOf(actionModel.get(i).interfaceName) >= 0) {
|
||||
actualModel.append(actionModel.get(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: ListModel {
|
||||
id: actualModel
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
width: parent.width
|
||||
text: model.text
|
||||
|
||||
onClicked: root.entrySelected(model.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,6 +21,45 @@ Page {
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: actionModel
|
||||
ListElement { interfaceName: "light"; text: "Switch lights..."; identifier: "switchLights" }
|
||||
ListElement { interfaceName: "mediacontroller"; text: "Control media playback..."; identifier: "controlMedia" }
|
||||
ListElement { interfaceName: "extendedvolumecontroller"; text: "Mute media playback..."; identifier: "muteMedia" }
|
||||
ListElement { interfaceName: "notifications"; text: "Notify me..."; identifier: "notify" }
|
||||
ListElement { interfaceName: ""; text: "Manually configure an action..."; identifier: "manualAction" }
|
||||
}
|
||||
|
||||
DevicesProxy {
|
||||
id: ifaceFilterModel
|
||||
devices: Engine.deviceManager.devices
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
actualModel.clear()
|
||||
for (var i = 0; i < actionModel.count; i++) {
|
||||
ifaceFilterModel.filterInterface = actionModel.get(i).interfaceName;
|
||||
if (actionModel.get(i).interfaceName === "" || ifaceFilterModel.count > 0) {
|
||||
actualModel.append(actionModel.get(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function actionSelected(identifier) {
|
||||
switch (identifier) {
|
||||
case "switchLights":
|
||||
pageStack.push(switchLightsCompoent)
|
||||
break;
|
||||
case "controlMedia":
|
||||
break;
|
||||
case "muteMedia":
|
||||
break;
|
||||
case "manualAction":
|
||||
pageStack.push(selectDeviceComponent)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
@ -35,26 +74,13 @@ Page {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
model: ListModel {
|
||||
ListElement { name: "switchLights"; text: "Switch lights..." }
|
||||
ListElement { name: "controlMedia"; text: "Control media playback..." }
|
||||
ListElement { name: "manualAction"; text: "Manually configure an action..." }
|
||||
id: actualModel
|
||||
}
|
||||
delegate: ItemDelegate {
|
||||
width: parent.width
|
||||
text: model.text
|
||||
onClicked: {
|
||||
switch (model.name) {
|
||||
case "switchLights":
|
||||
pageStack.push(switchLightsCompoent)
|
||||
break;
|
||||
case "controlMedia":
|
||||
break;
|
||||
case "muteMedia":
|
||||
break;
|
||||
case "manualAction":
|
||||
pageStack.push(selectDeviceComponent)
|
||||
break;
|
||||
}
|
||||
root.actionSelected(model.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
guh-control/ui/magic/SelectEventPage.qml
Normal file
46
guh-control/ui/magic/SelectEventPage.qml
Normal file
@ -0,0 +1,46 @@
|
||||
import QtQuick 2.4
|
||||
import QtQuick.Controls 2.1
|
||||
import "../components"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
property alias text: header.text
|
||||
property var device: null
|
||||
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
|
||||
header: GuhHeader {
|
||||
id: header
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: eventModel
|
||||
ListElement { interfaceName: "temperaturesensor"; text: "When it's freezing..."; event: "freeze"}
|
||||
ListElement { interfaceName: "battery"; text: "When the device runs out of battery..."; event: "lowBattery"}
|
||||
ListElement { interfaceName: "weather"; text: "When it starts raining..."; event: "rain" }
|
||||
}
|
||||
|
||||
onDeviceClassChanged: {
|
||||
actualModel.clear()
|
||||
print("device supports interfaces", deviceClass.interfaces)
|
||||
for (var i = 0; i < eventModel.count; i++) {
|
||||
print("event is for interface", eventModel.get(i).interfaceName)
|
||||
if (deviceClass.interfaces.indexOf(eventModel.get(i).interfaceName) >= 0) {
|
||||
actualModel.append(eventModel.get(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
model: ListModel {
|
||||
id: actualModel
|
||||
}
|
||||
|
||||
delegate: ItemDelegate {
|
||||
text: model.text
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -117,18 +117,28 @@ ApplicationWindow {
|
||||
return "Gateways"
|
||||
case "notifications":
|
||||
return "Notifications"
|
||||
case "temperaturesensor":
|
||||
return "Temperature";
|
||||
case "humiditysensor":
|
||||
return "Humidity";
|
||||
}
|
||||
}
|
||||
|
||||
function interfaceToIcon(name) {
|
||||
switch (name) {
|
||||
case "light":
|
||||
case "colorlight":
|
||||
case "dimmablelight":
|
||||
return Qt.resolvedUrl("images/torch-on.svg")
|
||||
case "sensor":
|
||||
return Qt.resolvedUrl("images/sensors.svg")
|
||||
case "media":
|
||||
case "mediacontroller":
|
||||
return Qt.resolvedUrl("images/mediaplayer-app-symbolic.svg")
|
||||
case "button":
|
||||
case "longpressbutton":
|
||||
case "multibutton":
|
||||
case "longpressmultibutton":
|
||||
return Qt.resolvedUrl("images/system-shutdown.svg")
|
||||
case "weather":
|
||||
return Qt.resolvedUrl("images/weather-app-symbolic.svg")
|
||||
|
||||
@ -10,6 +10,7 @@ class LogEntry : public QObject
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVariant value READ value CONSTANT)
|
||||
|
||||
Q_PROPERTY(QDateTime timestamp READ timestamp CONSTANT)
|
||||
Q_PROPERTY(QString timeString READ timeString CONSTANT)
|
||||
Q_PROPERTY(QString dayString READ dayString CONSTANT)
|
||||
Q_PROPERTY(QString dateString READ dateString CONSTANT)
|
||||
|
||||
@ -22,22 +22,22 @@
|
||||
|
||||
#include "param.h"
|
||||
|
||||
Param::Param(const QString &name, const QVariant &value, QObject *parent) :
|
||||
Param::Param(const QString &id, const QVariant &value, QObject *parent) :
|
||||
QObject(parent),
|
||||
m_name(name),
|
||||
m_id(id),
|
||||
m_value(value)
|
||||
{
|
||||
}
|
||||
|
||||
QString Param::name() const
|
||||
QString Param::id() const
|
||||
{
|
||||
return m_name;
|
||||
return m_id;
|
||||
}
|
||||
|
||||
void Param::setName(const QString &name)
|
||||
void Param::setId(const QString &id)
|
||||
{
|
||||
m_name = name;
|
||||
emit nameChanged();
|
||||
m_id = id;
|
||||
emit idChanged();
|
||||
}
|
||||
|
||||
QVariant Param::value() const
|
||||
|
||||
@ -30,24 +30,24 @@
|
||||
class Param : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
|
||||
Q_PROPERTY(QString id READ id WRITE setId NOTIFY idChanged)
|
||||
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
|
||||
|
||||
public:
|
||||
Param(const QString &name = QString(), const QVariant &value = QVariant(), QObject *parent = 0);
|
||||
Param(const QString &id = QString(), const QVariant &value = QVariant(), QObject *parent = 0);
|
||||
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
QString id() const;
|
||||
void setId(const QString &id);
|
||||
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_id;
|
||||
QVariant m_value;
|
||||
|
||||
signals:
|
||||
void nameChanged();
|
||||
void idChanged();
|
||||
void valueChanged();
|
||||
|
||||
};
|
||||
|
||||
@ -44,10 +44,10 @@ Param *Params::get(int index) const
|
||||
return m_params.at(index);
|
||||
}
|
||||
|
||||
Param *Params::getParam(QString name) const
|
||||
Param *Params::getParam(QString paramTypeId) const
|
||||
{
|
||||
foreach (Param *param, m_params) {
|
||||
if (param->name() == name) {
|
||||
if (param->id() == paramTypeId) {
|
||||
return param;
|
||||
}
|
||||
}
|
||||
@ -71,9 +71,9 @@ QVariant Params::data(const QModelIndex &index, int role) const
|
||||
return QVariant();
|
||||
|
||||
Param *param = m_params.at(index.row());
|
||||
if (role == NameRole) {
|
||||
return param->name();
|
||||
} else if (role == ValueRole) {
|
||||
if (role == RoleId) {
|
||||
return param->id();
|
||||
} else if (role == RoleValue) {
|
||||
return param->value();
|
||||
}
|
||||
return QVariant();
|
||||
@ -97,7 +97,7 @@ void Params::clearModel()
|
||||
QHash<int, QByteArray> Params::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[NameRole] = "name";
|
||||
roles[ValueRole] = "value";
|
||||
roles[RoleId] = "id";
|
||||
roles[RoleValue] = "value";
|
||||
return roles;
|
||||
}
|
||||
|
||||
@ -31,9 +31,9 @@ class Params : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ParamRole {
|
||||
NameRole = Qt::DisplayRole,
|
||||
ValueRole
|
||||
enum RoleId {
|
||||
RoleId,
|
||||
RoleValue
|
||||
};
|
||||
|
||||
explicit Params(QObject *parent = 0);
|
||||
@ -42,7 +42,7 @@ public:
|
||||
|
||||
Q_INVOKABLE int count() const;
|
||||
Q_INVOKABLE Param *get(int index) const;
|
||||
Q_INVOKABLE Param *getParam(QString name) const;
|
||||
Q_INVOKABLE Param *getParam(QString paramTypeId) const;
|
||||
|
||||
Q_INVOKABLE int paramCount() const;
|
||||
|
||||
|
||||
@ -57,6 +57,16 @@ void ParamType::setName(const QString &name)
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
QString ParamType::displayName() const
|
||||
{
|
||||
return m_displayName;
|
||||
}
|
||||
|
||||
void ParamType::setDisplayName(const QString &displayName)
|
||||
{
|
||||
m_displayName = displayName;
|
||||
}
|
||||
|
||||
QString ParamType::type() const
|
||||
{
|
||||
return m_type;
|
||||
|
||||
@ -35,6 +35,7 @@ class ParamType : public QObject
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid id READ id CONSTANT)
|
||||
Q_PROPERTY(QString name READ name CONSTANT)
|
||||
Q_PROPERTY(QString displayName READ displayName CONSTANT)
|
||||
Q_PROPERTY(QString type READ type CONSTANT)
|
||||
Q_PROPERTY(int index READ index CONSTANT)
|
||||
Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT)
|
||||
@ -55,6 +56,9 @@ public:
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
|
||||
QString displayName() const;
|
||||
void setDisplayName(const QString &displayName);
|
||||
|
||||
QString type() const;
|
||||
void setType(const QString &type);
|
||||
|
||||
@ -88,6 +92,7 @@ public:
|
||||
private:
|
||||
QUuid m_id;
|
||||
QString m_name;
|
||||
QString m_displayName;
|
||||
QString m_type;
|
||||
int m_index;
|
||||
QVariant m_defaultValue;
|
||||
|
||||
@ -37,10 +37,10 @@ ParamType *ParamTypes::get(int index) const
|
||||
return m_paramTypes.at(index);
|
||||
}
|
||||
|
||||
ParamType *ParamTypes::getParamType(const QString &name) const
|
||||
ParamType *ParamTypes::getParamType(const QString &id) const
|
||||
{
|
||||
foreach (ParamType *paramType, m_paramTypes) {
|
||||
if (paramType->name() == name) {
|
||||
if (paramType->id() == id) {
|
||||
return paramType;
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ public:
|
||||
QList<ParamType *> paramTypes();
|
||||
|
||||
Q_INVOKABLE ParamType *get(int index) const;
|
||||
Q_INVOKABLE ParamType *getParamType(const QString &name) const;
|
||||
Q_INVOKABLE ParamType *getParamType(const QString &id) const;
|
||||
|
||||
int rowCount(const QModelIndex & parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
|
||||
Reference in New Issue
Block a user