Add support for state based rule action params

This commit is contained in:
Michael Zanetti 2019-03-25 00:15:49 +01:00
parent 481dad7a02
commit aaa52e0359
9 changed files with 218 additions and 47 deletions

View File

@ -53,6 +53,32 @@ void RuleActionParam::setEventParamTypeId(const QString &eventParamTypeId)
} }
} }
QString RuleActionParam::stateDeviceId() const
{
return m_stateDeviceId;
}
void RuleActionParam::setStateDeviceId(const QString &stateDeviceId)
{
if (m_stateDeviceId != stateDeviceId) {
m_stateDeviceId = stateDeviceId;
emit stateDeviceIdChanged();
}
}
QString RuleActionParam::stateTypeId() const
{
return m_stateTypeId;
}
void RuleActionParam::setStateTypeId(const QString &stateTypeId)
{
if (m_stateTypeId != stateTypeId) {
m_stateTypeId = stateTypeId;
emit stateTypeIdChanged();
}
}
RuleActionParam *RuleActionParam::clone() const RuleActionParam *RuleActionParam::clone() const
{ {
RuleActionParam *ret = new RuleActionParam(); RuleActionParam *ret = new RuleActionParam();
@ -61,6 +87,8 @@ RuleActionParam *RuleActionParam::clone() const
ret->setValue(value()); ret->setValue(value());
ret->setEventTypeId(eventTypeId()); ret->setEventTypeId(eventTypeId());
ret->setEventParamTypeId(eventParamTypeId()); ret->setEventParamTypeId(eventParamTypeId());
ret->setStateDeviceId(stateDeviceId());
ret->setStateTypeId(stateTypeId());
return ret; return ret;
} }
@ -72,6 +100,8 @@ bool RuleActionParam::operator==(RuleActionParam *other) const
COMPARE(m_paramName, other->paramName()); COMPARE(m_paramName, other->paramName());
COMPARE(m_eventTypeId, other->eventTypeId()); COMPARE(m_eventTypeId, other->eventTypeId());
COMPARE(m_eventParamTypeId, other->eventParamTypeId()); COMPARE(m_eventParamTypeId, other->eventParamTypeId());
COMPARE(m_stateDeviceId, other->stateDeviceId());
COMPARE(m_stateTypeId, other->stateTypeId());
COMPARE(m_value, other->value()); COMPARE(m_value, other->value());
return true; return true;
} }

View File

@ -13,6 +13,8 @@ class RuleActionParam : public Param
Q_PROPERTY(QString paramName READ paramName WRITE setParamName NOTIFY paramNameChanged) Q_PROPERTY(QString paramName READ paramName WRITE setParamName NOTIFY paramNameChanged)
Q_PROPERTY(QString eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged) Q_PROPERTY(QString eventTypeId READ eventTypeId WRITE setEventTypeId NOTIFY eventTypeIdChanged)
Q_PROPERTY(QString eventParamTypeId READ eventParamTypeId WRITE setEventParamTypeId NOTIFY eventParamTypeIdChanged) Q_PROPERTY(QString eventParamTypeId READ eventParamTypeId WRITE setEventParamTypeId NOTIFY eventParamTypeIdChanged)
Q_PROPERTY(QString stateDeviceId READ stateDeviceId WRITE setStateDeviceId NOTIFY stateDeviceIdChanged)
Q_PROPERTY(QString stateTypeId READ stateTypeId WRITE setStateTypeId NOTIFY stateTypeIdChanged)
public: public:
explicit RuleActionParam(const QString &paramName, const QVariant &value, QObject *parent = nullptr); explicit RuleActionParam(const QString &paramName, const QVariant &value, QObject *parent = nullptr);
explicit RuleActionParam(QObject *parent = nullptr); explicit RuleActionParam(QObject *parent = nullptr);
@ -26,17 +28,27 @@ public:
QString eventParamTypeId() const; QString eventParamTypeId() const;
void setEventParamTypeId(const QString &eventParamTypeId); void setEventParamTypeId(const QString &eventParamTypeId);
QString stateDeviceId() const;
void setStateDeviceId(const QString &stateDeviceId);
QString stateTypeId() const;
void setStateTypeId(const QString &stateTypeId);
RuleActionParam* clone() const; RuleActionParam* clone() const;
bool operator==(RuleActionParam *other) const; bool operator==(RuleActionParam *other) const;
signals: signals:
void paramNameChanged(); void paramNameChanged();
void eventTypeIdChanged(); void eventTypeIdChanged();
void eventParamTypeIdChanged(); void eventParamTypeIdChanged();
void stateDeviceIdChanged();
void stateTypeIdChanged();
protected: protected:
QString m_paramName; QString m_paramName;
QString m_eventTypeId; QString m_eventTypeId;
QString m_eventParamTypeId; QString m_eventParamTypeId;
QString m_stateDeviceId;
QString m_stateTypeId;
}; };
#endif // RULEACTIONPARAM_H #endif // RULEACTIONPARAM_H

View File

@ -94,6 +94,22 @@ void RuleActionParams::setRuleActionParamEvent(const QString &paramTypeId, const
addRuleActionParam(rap); addRuleActionParam(rap);
} }
void RuleActionParams::setRuleActionParamState(const QString &paramTypeId, const QString &stateDeviceId, const QString &stateTypeId)
{
foreach (RuleActionParam *rap, m_list) {
if (rap->paramTypeId() == paramTypeId) {
rap->setStateDeviceId(stateDeviceId);
rap->setStateTypeId(stateTypeId);
return;
}
}
RuleActionParam *rap = new RuleActionParam(this);
rap->setParamTypeId(paramTypeId);
rap->setStateDeviceId(stateDeviceId);
rap->setStateTypeId(stateTypeId);
addRuleActionParam(rap);
}
RuleActionParam *RuleActionParams::get(int index) const RuleActionParam *RuleActionParams::get(int index) const
{ {
return m_list.at(index); return m_list.at(index);

View File

@ -29,6 +29,8 @@ public:
Q_INVOKABLE void setRuleActionParam(const QString &paramTypeId, const QVariant &value); Q_INVOKABLE void setRuleActionParam(const QString &paramTypeId, const QVariant &value);
Q_INVOKABLE void setRuleActionParamByName(const QString &paramName, const QVariant &value); Q_INVOKABLE void setRuleActionParamByName(const QString &paramName, const QVariant &value);
Q_INVOKABLE void setRuleActionParamEvent(const QString &paramTypeId, const QString &eventTypeId, const QString &eventParamTypeId); Q_INVOKABLE void setRuleActionParamEvent(const QString &paramTypeId, const QString &eventTypeId, const QString &eventParamTypeId);
Q_INVOKABLE void setRuleActionParamState(const QString &paramTypeId, const QString &stateDeviceId, const QString &stateTypeId);
Q_INVOKABLE RuleActionParam* get(int index) const; Q_INVOKABLE RuleActionParam* get(int index) const;
bool operator==(RuleActionParams *other) const; bool operator==(RuleActionParams *other) const;

View File

@ -179,5 +179,6 @@
<file>ui/components/Imprint.qml</file> <file>ui/components/Imprint.qml</file>
<file>ui/appsettings/LookAndFeelSettingsPage.qml</file> <file>ui/appsettings/LookAndFeelSettingsPage.qml</file>
<file>ui/appsettings/AppLogPage.qml</file> <file>ui/appsettings/AppLogPage.qml</file>
<file>ui/magic/SelectStatePage.qml</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -38,27 +38,32 @@ Dialog {
} }
ThinDivider {} ThinDivider {}
Button { MeaListItemDelegate {
text: qsTr("Remove all those rules")
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Remove all those rules")
progressive: false
onClicked: { onClicked: {
engine.deviceManager.removeDevice(root.device.id, DeviceManager.RemovePolicyCascade) engine.deviceManager.removeDevice(root.device.id, DeviceManager.RemovePolicyCascade)
root.close() root.close()
root.destroy(); root.destroy();
} }
} }
Button {
MeaListItemDelegate {
text: qsTr("Update rules, removing this thing") text: qsTr("Update rules, removing this thing")
Layout.fillWidth: true Layout.fillWidth: true
progressive: false
onClicked: { onClicked: {
engine.deviceManager.removeDevice(root.device.id, DeviceManager.RemovePolicyUpdate) engine.deviceManager.removeDevice(root.device.id, DeviceManager.RemovePolicyUpdate)
root.close() root.close()
root.destroy(); root.destroy();
} }
} }
Button {
MeaListItemDelegate {
text: qsTr("Don't remove this thing") text: qsTr("Don't remove this thing")
Layout.fillWidth: true Layout.fillWidth: true
progressive: false
onClicked: { onClicked: {
root.close() root.close()
root.destroy(); root.destroy();

View File

@ -16,6 +16,8 @@ ItemDelegate {
value: paramType.defaultValue value: paramType.defaultValue
} }
property bool writable: true property bool writable: true
property alias nameVisible: nameLabel.visible
property string placeholderText: ""
topPadding: 0 topPadding: 0
bottomPadding: 0 bottomPadding: 0
@ -23,6 +25,7 @@ ItemDelegate {
id: contentItemColumn id: contentItemColumn
RowLayout { RowLayout {
Label { Label {
id: nameLabel
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumWidth: parent.width / 2 Layout.minimumWidth: parent.width / 2
text: root.paramType.displayName text: root.paramType.displayName
@ -90,7 +93,6 @@ ItemDelegate {
} }
return root.param.value; return root.param.value;
} }
} }
} }
Component { Component {
@ -188,6 +190,7 @@ ItemDelegate {
root.param.value = text; root.param.value = text;
} }
} }
placeholderText: root.placeholderText
} }
} }

View File

@ -22,7 +22,7 @@ Page {
signal completed(); signal completed();
header: GuhHeader { header: GuhHeader {
text: "params" text: actionType.displayName
onBackPressed: root.backPressed(); onBackPressed: root.backPressed();
} }
@ -46,6 +46,9 @@ Page {
if (eventParamRadioButton.checked) { if (eventParamRadioButton.checked) {
return "event" return "event"
} }
if (stateValueRadioButton.checked) {
return "state"
}
return "" return ""
} }
@ -53,54 +56,115 @@ Page {
property alias value: paramDelegate.value property alias value: paramDelegate.value
property alias eventType: eventParamsComboBox.eventType property alias eventType: eventParamsComboBox.eventType
property alias eventParamTypeId: eventParamsComboBox.currentParamTypeId property alias eventParamTypeId: eventParamsComboBox.currentParamTypeId
property alias stateDeviceId: statePickerDelegate.deviceId
property alias stateTypeId: statePickerDelegate.stateTypeId
RadioButton { GroupBox {
id: staticParamRadioButton
text: qsTr("Use static value as parameter")
checked: true
}
ParamDelegate {
id: paramDelegate
Layout.fillWidth: true
paramType: root.actionType.paramTypes.get(index)
enabled: staticParamRadioButton.checked
}
RadioButton {
id: eventParamRadioButton
text: qsTr("Use event parameter")
visible: eventParamsComboBox.count > 0
}
ComboBox {
id: eventParamsComboBox
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: app.margins Layout.margins: app.margins
enabled: eventParamRadioButton.checked title: paramType.displayName
visible: count > 0 ColumnLayout {
Component.onCompleted: currentIndex = 0;
property var eventDescriptor: root.rule.eventDescriptors.count === 1 ? root.rule.eventDescriptors.get(0) : null
property var device: eventDescriptor ? engine.deviceManager.devices.getDevice(eventDescriptor.deviceId) : null
property var deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId) : null
property var currentParamDescriptor: eventType.paramTypes.get(eventParamsComboBox.currentIndex)
property var currentParamTypeId: currentParamDescriptor.id
model: eventType.paramTypes
delegate: ItemDelegate {
width: parent.width
text: eventParamsComboBox.device.name + " - " + eventParamsComboBox.eventType.displayName + " - " + eventParamsComboBox.eventType.paramTypes.getParamType(model.id).displayName
}
contentItem: Label {
id: eventParamsComboBoxContentItem
anchors.fill: parent anchors.fill: parent
anchors.margins: app.margins RadioButton {
text: eventParamsComboBox.device.name + " - " + eventParamsComboBox.eventType.displayName + " - " + eventParamsComboBox.currentParamDescriptor.displayName id: staticParamRadioButton
elide: Text.ElideRight text: qsTr("Use static value as parameter")
checked: true
font.pixelSize: app.smallFont
}
RadioButton {
id: eventParamRadioButton
text: qsTr("Use event parameter")
visible: eventParamsComboBox.count > 0
font.pixelSize: app.smallFont
}
RadioButton {
id: stateValueRadioButton
text: qsTr("Use a thing's state value")
font.pixelSize: app.smallFont
}
ThinDivider {}
ParamDelegate {
id: paramDelegate
Layout.fillWidth: true
paramType: root.actionType.paramTypes.get(index)
enabled: staticParamRadioButton.checked
nameVisible: false
visible: staticParamRadioButton.checked
placeholderText: qsTr("Insert value here")
}
ComboBox {
id: eventParamsComboBox
Layout.fillWidth: true
visible: eventParamRadioButton.checked && count > 0
Component.onCompleted: currentIndex = 0;
property var eventDescriptor: root.rule.eventDescriptors.count === 1 ? root.rule.eventDescriptors.get(0) : null
property var device: eventDescriptor ? engine.deviceManager.devices.getDevice(eventDescriptor.deviceId) : null
property var deviceClass: device ? engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
property var eventType: deviceClass ? deviceClass.eventTypes.getEventType(eventDescriptor.eventTypeId) : null
property var currentParamDescriptor: eventType.paramTypes.get(eventParamsComboBox.currentIndex)
property var currentParamTypeId: currentParamDescriptor.id
model: eventType.paramTypes
delegate: ItemDelegate {
width: parent.width
text: eventParamsComboBox.device.name + " - " + eventParamsComboBox.eventType.displayName + " - " + eventParamsComboBox.eventType.paramTypes.getParamType(model.id).displayName
}
contentItem: Label {
id: eventParamsComboBoxContentItem
anchors.fill: parent
anchors.margins: app.margins
text: eventParamsComboBox.device.name + " - " + eventParamsComboBox.eventType.displayName + " - " + eventParamsComboBox.currentParamDescriptor.displayName
elide: Text.ElideRight
}
}
MeaListItemDelegate {
id: statePickerDelegate
Layout.fillWidth: true
text: deviceId === null || stateTypeId === null
? qsTr("Select a state")
: dev.name + " - " + dev.deviceClass.stateTypes.getStateType(stateTypeId).displayName
visible: stateValueRadioButton.checked
property var deviceId: null
property var stateTypeId: null
readonly property Device dev: engine.deviceManager.devices.getDevice(deviceId)
onClicked: {
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"), {showStates: true, showEvents: false, showActions: false });
page.thingSelected.connect(function(device) {
print("Thing selected", device.name);
statePickerDelegate.deviceId = device.id
var selectStatePage = pageStack.replace(Qt.resolvedUrl("SelectStatePage.qml"), {device: device})
selectStatePage.stateSelected.connect(function(stateTypeId) {
print("State selected", stateTypeId)
pageStack.pop();
statePickerDelegate.stateTypeId = stateTypeId;
})
})
}
}
} }
} }
ThinDivider {} // Label {
// id: paramNameLabel
// Layout.fillWidth: true
// Layout.leftMargin: app.margins
// Layout.rightMargin: app.margins
// Layout.topMargin: app.margins
// elide: Text.ElideRight
// text: paramType.displayName
// font.pixelSize: app.largeFont
// }
// ThinDivider {}
} }
} }
Item { Item {
@ -124,6 +188,9 @@ Page {
} else if (paramDelegate.type === "event") { } else if (paramDelegate.type === "event") {
print("adding event based rule action param", paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId) print("adding event based rule action param", paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId)
root.ruleAction.ruleActionParams.setRuleActionParamEvent(paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId) root.ruleAction.ruleActionParams.setRuleActionParamEvent(paramDelegate.paramType.id, paramDelegate.eventType.id, paramDelegate.eventParamTypeId)
} else if (paramDelegate.type === "state") {
print("adding state value based rule action param", paramDelegate.paramType.id, paramDelegate.stateDeviceId, paramDelegate.stateTypeId)
root.ruleAction.ruleActionParams.setRuleActionParamState(paramDelegate.paramType.id, paramDelegate.stateDeviceId, paramDelegate.stateTypeId)
} }
} }
root.completed() root.completed()

View File

@ -0,0 +1,35 @@
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.2
import "../components"
import "../delegates"
import Nymea 1.0
Page {
id: root
header: GuhHeader {
text: qsTr("Select state")
onBackPressed: pageStack.pop()
}
property Device device: null
signal stateSelected(var stateTypeId);
ListView {
anchors.fill: parent
model: device.deviceClass.stateTypes
delegate: MeaListItemDelegate {
width: parent.width
iconName: "../images/state.svg"
text: model.displayName
subText: root.device.states.getState(model.id).value
prominentSubText: false
onClicked: {
root.stateSelected(model.id)
}
}
}
}