more work on states
parent
5a32fe57de
commit
c382d13e70
|
|
@ -133,7 +133,6 @@ void DeviceManager::getSupportedDevicesResponse(const QVariantMap ¶ms)
|
|||
QVariantList deviceClassList = params.value("params").toMap().value("deviceClasses").toList();
|
||||
foreach (QVariant deviceClassVariant, deviceClassList) {
|
||||
DeviceClass *deviceClass = JsonTypes::unpackDeviceClass(deviceClassVariant.toMap(), Engine::instance()->deviceManager()->deviceClasses());
|
||||
qDebug() << "Server has device class:" << deviceClass->name() << deviceClass->id();
|
||||
m_deviceClasses->addDeviceClass(deviceClass);
|
||||
}
|
||||
}
|
||||
|
|
@ -280,7 +279,7 @@ void DeviceManager::addDiscoveredDevice(const QUuid &deviceClassId, const QUuid
|
|||
params.insert("deviceClassId", deviceClassId.toString());
|
||||
params.insert("name", name);
|
||||
params.insert("deviceDescriptorId", deviceDescriptorId.toString());
|
||||
m_jsonClient->sendCommand("Devices.AddConfiguredDevice", params);
|
||||
m_jsonClient->sendCommand("Devices.AddConfiguredDevice", params, this, "addDeviceResponse");
|
||||
}
|
||||
|
||||
void DeviceManager::pairDevice(const QUuid &deviceClassId, const QUuid &deviceDescriptorId, const QString &name)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ void UpnpDiscovery::readData()
|
|||
|
||||
|
||||
if (key.contains("Server") || key.contains("SERVER")) {
|
||||
if (value.contains("guh")) {
|
||||
if (value.contains("nymea")) {
|
||||
qDebug() << " --> " << key << value;
|
||||
isGuh = true;
|
||||
}
|
||||
|
|
@ -160,6 +160,10 @@ void UpnpDiscovery::readData()
|
|||
}
|
||||
}
|
||||
|
||||
if (isGuh) {
|
||||
qDebug() << "Found guh device:" << location;
|
||||
}
|
||||
|
||||
if (!m_foundDevices.contains(location) && isGuh) {
|
||||
m_foundDevices.append(location);
|
||||
DiscoveryDevice discoveryDevice;
|
||||
|
|
@ -201,7 +205,7 @@ void UpnpDiscovery::networkReplyFinished(QNetworkReply *reply)
|
|||
}
|
||||
|
||||
if (xml.isStartElement()) {
|
||||
if (xml.name().toString() == "guhRpcURL") {
|
||||
if (xml.name().toString() == "nymeaRpcURL") {
|
||||
discoveryDevice.setGuhRpcUrl(xml.readElementText());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ bool ZeroconfDiscovery::discovering() const
|
|||
#ifdef WITH_AVAHI
|
||||
void ZeroconfDiscovery::serviceEntryAdded(const AvahiServiceEntry &entry)
|
||||
{
|
||||
if (!entry.name().startsWith("guhIO") || entry.serviceType() != "_jsonrpc._tcp") {
|
||||
if (!entry.name().startsWith("nymea") || entry.serviceType() != "_jsonrpc._tcp") {
|
||||
return;
|
||||
}
|
||||
qDebug() << "avahi service entry added" << entry.name() << entry.hostAddress() << entry.port() << entry.txt() << entry.serviceType();
|
||||
|
|
@ -57,7 +57,7 @@ void ZeroconfDiscovery::serviceEntryAdded(const AvahiServiceEntry &entry)
|
|||
dev.setHostAddress(entry.hostAddress());
|
||||
dev.setPort(entry.port());
|
||||
dev.setFriendlyName(entry.hostName());
|
||||
dev.setGuhRpcUrl(QString("%1://%2:%3").arg(sslEnabled ? "guhs" : "guh").arg(entry.hostAddress().toString()).arg(entry.port()));
|
||||
dev.setGuhRpcUrl(QString("%1://%2:%3").arg(sslEnabled ? "nymeas" : "nymea").arg(entry.hostAddress().toString()).arg(entry.port()));
|
||||
m_discoveryModel->addDevice(dev);
|
||||
|
||||
// DiscoveryDevice *dev = new DiscoveryDevice();
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ QString GuhConnection::url() const
|
|||
void GuhConnection::sendData(const QByteArray &data)
|
||||
{
|
||||
if (connected()) {
|
||||
qDebug() << "sending data:" << data;
|
||||
// qDebug() << "sending data:" << data;
|
||||
m_currentInterface->sendData(data);
|
||||
} else {
|
||||
qWarning() << "Not connected. Cannot send.";
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@
|
|||
#include "types/eventdescriptors.h"
|
||||
#include "types/ruleactionparam.h"
|
||||
#include "types/ruleactionparams.h"
|
||||
#include "types/stateevaluator.h"
|
||||
#include "types/stateevaluators.h"
|
||||
#include "types/statedescriptor.h"
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
|
|
@ -223,56 +226,74 @@ QVariantMap JsonTypes::packRule(Rule *rule)
|
|||
ret.insert("name", rule->name());
|
||||
ret.insert("enabled", rule->enabled());
|
||||
|
||||
if (rule->ruleActions()->rowCount() > 0) {
|
||||
QVariantList actions;
|
||||
for (int i = 0; i < rule->ruleActions()->rowCount(); i++) {
|
||||
QVariantMap ruleAction;
|
||||
ruleAction.insert("actionTypeId", rule->ruleActions()->get(i)->actionTypeId());
|
||||
ruleAction.insert("deviceId", rule->ruleActions()->get(i)->deviceId());
|
||||
if (rule->ruleActions()->get(i)->ruleActionParams()->rowCount() > 0) {
|
||||
QVariantList ruleActionParams;
|
||||
for (int j = 0; j < rule->ruleActions()->get(i)->ruleActionParams()->rowCount(); j++) {
|
||||
QVariantMap ruleActionParam;
|
||||
ruleActionParam.insert("paramTypeId", rule->ruleActions()->get(i)->ruleActionParams()->get(j)->paramTypeId());
|
||||
ruleActionParam.insert("value", rule->ruleActions()->get(i)->ruleActionParams()->get(j)->value());
|
||||
ruleActionParams.append(ruleActionParam);
|
||||
}
|
||||
ruleAction.insert("ruleActionParams", ruleActionParams);
|
||||
}
|
||||
actions.append(ruleAction);
|
||||
}
|
||||
ret.insert("actions", actions);
|
||||
if (rule->actions()->rowCount() > 0) {
|
||||
ret.insert("actions", packRuleActions(rule->actions()));
|
||||
}
|
||||
if (rule->exitActions()->rowCount() > 0) {
|
||||
ret.insert("exitActions", packRuleActions(rule->exitActions()));
|
||||
}
|
||||
|
||||
if (rule->eventDescriptors()->rowCount() > 0) {
|
||||
QVariantList eventDescriptors;
|
||||
for (int i = 0; i < rule->eventDescriptors()->rowCount(); i++) {
|
||||
QVariantMap eventDescriptorMap;
|
||||
EventDescriptor* eventDescriptor = rule->eventDescriptors()->get(i);
|
||||
if (!eventDescriptor->deviceId().isNull() && !eventDescriptor->eventTypeId().isNull()) {
|
||||
eventDescriptorMap.insert("eventTypeId", eventDescriptor->eventTypeId());
|
||||
eventDescriptorMap.insert("deviceId", eventDescriptor->deviceId());
|
||||
} else {
|
||||
eventDescriptorMap.insert("interface", eventDescriptor->interfaceName());
|
||||
eventDescriptorMap.insert("interfaceEvent", eventDescriptor->interfaceEvent());
|
||||
}
|
||||
if (eventDescriptor->paramDescriptors()->rowCount() > 0) {
|
||||
QVariantList paramDescriptors;
|
||||
for (int j = 0; j < rule->eventDescriptors()->get(i)->paramDescriptors()->rowCount(); j++) {
|
||||
QVariantMap paramDescriptor;
|
||||
paramDescriptor.insert("paramTypeId", rule->eventDescriptors()->get(i)->paramDescriptors()->get(j)->paramTypeId());
|
||||
paramDescriptor.insert("value", rule->eventDescriptors()->get(i)->paramDescriptors()->get(j)->value());
|
||||
QMetaEnum operatorEnum = QMetaEnum::fromType<ParamDescriptor::ValueOperator>();
|
||||
paramDescriptor.insert("operator", operatorEnum.valueToKey(rule->eventDescriptors()->get(i)->paramDescriptors()->get(j)->operatorType()));
|
||||
paramDescriptors.append(paramDescriptor);
|
||||
}
|
||||
eventDescriptorMap.insert("paramDescriptors", paramDescriptors);
|
||||
}
|
||||
eventDescriptors.append(eventDescriptorMap);
|
||||
}
|
||||
ret.insert("eventDescriptors", eventDescriptors);
|
||||
ret.insert("eventDescriptors", packEventDescriptors(rule->eventDescriptors()));
|
||||
}
|
||||
|
||||
if (rule->stateEvaluator()) {
|
||||
ret.insert("stateEvaluator", packStateEvaluator(rule->stateEvaluator()));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packRuleActions(RuleActions *ruleActions)
|
||||
{
|
||||
QVariantList ret;
|
||||
for (int i = 0; i < ruleActions->rowCount(); i++) {
|
||||
QVariantMap ruleAction;
|
||||
ruleAction.insert("actionTypeId", ruleActions->get(i)->actionTypeId());
|
||||
ruleAction.insert("deviceId", ruleActions->get(i)->deviceId());
|
||||
if (ruleActions->get(i)->ruleActionParams()->rowCount() > 0) {
|
||||
QVariantList ruleActionParams;
|
||||
for (int j = 0; j < ruleActions->get(i)->ruleActionParams()->rowCount(); j++) {
|
||||
QVariantMap ruleActionParam;
|
||||
ruleActionParam.insert("paramTypeId", ruleActions->get(i)->ruleActionParams()->get(j)->paramTypeId());
|
||||
ruleActionParam.insert("value", ruleActions->get(i)->ruleActionParams()->get(j)->value());
|
||||
ruleActionParams.append(ruleActionParam);
|
||||
}
|
||||
ruleAction.insert("ruleActionParams", ruleActionParams);
|
||||
}
|
||||
ret.append(ruleAction);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVariantList JsonTypes::packEventDescriptors(EventDescriptors *eventDescriptors)
|
||||
{
|
||||
QVariantList ret;
|
||||
for (int i = 0; i < eventDescriptors->rowCount(); i++) {
|
||||
QVariantMap eventDescriptorMap;
|
||||
EventDescriptor* eventDescriptor = eventDescriptors->get(i);
|
||||
if (!eventDescriptor->deviceId().isNull() && !eventDescriptor->eventTypeId().isNull()) {
|
||||
eventDescriptorMap.insert("eventTypeId", eventDescriptor->eventTypeId());
|
||||
eventDescriptorMap.insert("deviceId", eventDescriptor->deviceId());
|
||||
} else {
|
||||
eventDescriptorMap.insert("interface", eventDescriptor->interfaceName());
|
||||
eventDescriptorMap.insert("interfaceEvent", eventDescriptor->interfaceEvent());
|
||||
}
|
||||
if (eventDescriptor->paramDescriptors()->rowCount() > 0) {
|
||||
QVariantList paramDescriptors;
|
||||
for (int j = 0; j < eventDescriptor->paramDescriptors()->rowCount(); j++) {
|
||||
QVariantMap paramDescriptor;
|
||||
paramDescriptor.insert("paramTypeId", eventDescriptor->paramDescriptors()->get(j)->paramTypeId());
|
||||
paramDescriptor.insert("value", eventDescriptor->paramDescriptors()->get(j)->value());
|
||||
QMetaEnum operatorEnum = QMetaEnum::fromType<ParamDescriptor::ValueOperator>();
|
||||
paramDescriptor.insert("operator", operatorEnum.valueToKey(eventDescriptor->paramDescriptors()->get(j)->operatorType()));
|
||||
paramDescriptors.append(paramDescriptor);
|
||||
}
|
||||
eventDescriptorMap.insert("paramDescriptors", paramDescriptors);
|
||||
}
|
||||
ret.append(eventDescriptorMap);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -284,6 +305,26 @@ QVariantMap JsonTypes::packParam(Param *param)
|
|||
return ret;
|
||||
}
|
||||
|
||||
QVariantMap JsonTypes::packStateEvaluator(StateEvaluator *stateEvaluator)
|
||||
{
|
||||
QVariantMap ret;
|
||||
QMetaEnum stateOperatorEnum = QMetaEnum::fromType<StateEvaluator::StateOperator>();
|
||||
ret.insert("operator", stateOperatorEnum.valueToKey(stateEvaluator->stateOperator()));
|
||||
QVariantMap stateDescriptor;
|
||||
stateDescriptor.insert("deviceId", stateEvaluator->stateDescriptor()->deviceId());
|
||||
QMetaEnum valueOperatorEnum = QMetaEnum::fromType<StateDescriptor::ValueOperator>();
|
||||
stateDescriptor.insert("operator", valueOperatorEnum.valueToKeys(stateEvaluator->stateDescriptor()->valueOperator()));
|
||||
stateDescriptor.insert("stateTypeId", stateEvaluator->stateDescriptor()->stateTypeId());
|
||||
stateDescriptor.insert("value", stateEvaluator->stateDescriptor()->value());
|
||||
ret.insert("stateDescriptor", stateDescriptor);
|
||||
QVariantList childEvaluators;
|
||||
for (int i = 0; i < stateEvaluator->childEvaluators()->rowCount(); i++) {
|
||||
childEvaluators.append(packStateEvaluator(stateEvaluator->childEvaluators()->get(i)));
|
||||
}
|
||||
ret.insert("childEvaluators", childEvaluators);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DeviceClass::SetupMethod JsonTypes::stringToSetupMethod(const QString &setupMethodString)
|
||||
{
|
||||
if (setupMethodString == "SetupMethodJustAdd") {
|
||||
|
|
|
|||
|
|
@ -27,17 +27,22 @@
|
|||
#include <QUuid>
|
||||
|
||||
#include "types/types.h"
|
||||
#include "types/device.h"
|
||||
#include "types/plugin.h"
|
||||
#include "types/deviceclass.h"
|
||||
#include "types/paramtype.h"
|
||||
#include "types/statetype.h"
|
||||
#include "types/state.h"
|
||||
#include "types/eventtype.h"
|
||||
#include "types/actiontype.h"
|
||||
|
||||
class Plugin;
|
||||
class Vendor;
|
||||
|
||||
class StateType;
|
||||
class EventType;
|
||||
class ActionType;
|
||||
class ParamType;
|
||||
|
||||
class Device;
|
||||
class Param;
|
||||
class Rule;
|
||||
class StateEvaluator;
|
||||
class RuleActions;
|
||||
class EventDescriptors;
|
||||
|
||||
class JsonTypes : public QObject
|
||||
{
|
||||
|
|
@ -56,7 +61,10 @@ public:
|
|||
static Device *unpackDevice(const QVariantMap &deviceMap, QObject *parent);
|
||||
|
||||
static QVariantMap packRule(Rule* rule);
|
||||
static QVariantList packRuleActions(RuleActions* ruleActions);
|
||||
static QVariantList packEventDescriptors(EventDescriptors* eventDescriptors);
|
||||
static QVariantMap packParam(Param *param);
|
||||
static QVariantMap packStateEvaluator(StateEvaluator* stateEvaluator);
|
||||
private:
|
||||
static DeviceClass::SetupMethod stringToSetupMethod(const QString &setupMethodString);
|
||||
static QList<DeviceClass::BasicTag> stringListToBasicTags(const QStringList &basicTagsStringList);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@
|
|||
#include "types/rule.h"
|
||||
#include "types/interfaces.h"
|
||||
#include "types/interface.h"
|
||||
#include "types/statedescriptor.h"
|
||||
#include "types/stateevaluator.h"
|
||||
#include "types/stateevaluators.h"
|
||||
#include "models/logsmodel.h"
|
||||
#include "models/valuelogsproxymodel.h"
|
||||
#include "basicconfiguration.h"
|
||||
|
|
@ -131,6 +134,9 @@ int main(int argc, char *argv[])
|
|||
qmlRegisterType<Param>(uri, 1, 0, "Param");
|
||||
qmlRegisterUncreatableType<ParamDescriptor>(uri, 1, 0, "ParamDescriptor", "Uncreatable");
|
||||
qmlRegisterUncreatableType<ParamDescriptors>(uri, 1, 0, "ParamDescriptors", "Uncreatable");
|
||||
qmlRegisterUncreatableType<StateDescriptor>(uri, 1, 0, "StateDescriptor", "Uncreatable");
|
||||
qmlRegisterUncreatableType<StateEvaluator>(uri, 1, 0, "StateEvaluator", "Uncreatable");
|
||||
qmlRegisterUncreatableType<StateEvaluators>(uri, 1, 0, "StateEvaluators", "Uncreatable");
|
||||
|
||||
qmlRegisterUncreatableType<Interface>(uri, 1, 0, "Interface", "Uncreatable");
|
||||
qmlRegisterSingletonType<Interfaces>(uri, 1, 0, "Interfaces", interfacesModel_provider);
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ void LogsModel::update()
|
|||
|
||||
void LogsModel::logsReply(const QVariantMap &data)
|
||||
{
|
||||
qDebug() << "logs reply";
|
||||
qDebug() << "logs reply" << data;
|
||||
m_busy = false;
|
||||
emit busyChanged();
|
||||
beginResetModel();
|
||||
|
|
@ -167,12 +167,12 @@ void LogsModel::logsReply(const QVariantMap &data)
|
|||
QVariantMap entryMap = logEntryVariant.toMap();
|
||||
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
|
||||
QString deviceId = entryMap.value("deviceId").toString();
|
||||
QVariant value = entryMap.value("value");
|
||||
QString typeId = entryMap.value("typeId").toString();
|
||||
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();
|
||||
LogEntry::LoggingSource loggingSource = (LogEntry::LoggingSource)sourceEnum.keyToValue(entryMap.value("source").toByteArray());
|
||||
QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType<LogEntry::LoggingEventType>();
|
||||
LogEntry::LoggingEventType loggingEventType = (LogEntry::LoggingEventType)loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray());
|
||||
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
|
||||
LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this);
|
||||
m_list.append(entry);
|
||||
}
|
||||
|
|
@ -191,12 +191,12 @@ void LogsModel::newLogEntryReceived(const QVariantMap &data)
|
|||
QVariantMap entryMap = data;
|
||||
QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong());
|
||||
QString deviceId = entryMap.value("deviceId").toString();
|
||||
QVariant value = entryMap.value("value");
|
||||
QString typeId = entryMap.value("typeId").toString();
|
||||
QMetaEnum sourceEnum = QMetaEnum::fromType<LogEntry::LoggingSource>();
|
||||
LogEntry::LoggingSource loggingSource = (LogEntry::LoggingSource)sourceEnum.keyToValue(entryMap.value("source").toByteArray());
|
||||
QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType<LogEntry::LoggingEventType>();
|
||||
LogEntry::LoggingEventType loggingEventType = (LogEntry::LoggingEventType)loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray());
|
||||
QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value");
|
||||
LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this);
|
||||
m_list.append(entry);
|
||||
endInsertRows();
|
||||
|
|
|
|||
|
|
@ -66,8 +66,17 @@ bool RulesFilterModel::filterAcceptsRow(int source_row, const QModelIndex &sourc
|
|||
found = true;
|
||||
}
|
||||
if (!found) {
|
||||
for (int i = 0; i < rule->ruleActions()->rowCount(); i++) {
|
||||
RuleAction *ra = rule->ruleActions()->get(i);
|
||||
for (int i = 0; i < rule->actions()->rowCount(); i++) {
|
||||
RuleAction *ra = rule->actions()->get(i);
|
||||
if (ra->deviceId() == m_filterDeviceId) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
for (int i = 0; i < rule->exitActions()->rowCount(); i++) {
|
||||
RuleAction *ra = rule->exitActions()->get(i);
|
||||
if (ra->deviceId() == m_filterDeviceId) {
|
||||
found = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -134,5 +134,11 @@
|
|||
<file>ui/fonts/Ubuntu-R.ttf</file>
|
||||
<file>ui/fonts/Ubuntu-RI.ttf</file>
|
||||
<file>ui/components/InterfacesModels.qml</file>
|
||||
<file>ui/magic/StateEvaluatorDelegate.qml</file>
|
||||
<file>ui/magic/EditStateEvaluatorPage.qml</file>
|
||||
<file>ui/actiondelegates-ng/ActionDelegate.qml</file>
|
||||
<file>ui/magic/SimpleStateEvaluatorDelegate.qml</file>
|
||||
<file>ui/magic/SelectStateDescriptorParamsPage.qml</file>
|
||||
<file>ui/magic/SelectStateDescriptorPage.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "types/ruleactionparams.h"
|
||||
#include "types/ruleactionparam.h"
|
||||
#include "types/stateevaluator.h"
|
||||
#include "types/stateevaluators.h"
|
||||
#include "types/statedescriptor.h"
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
|
@ -68,6 +69,7 @@ void RuleManager::removeRule(const QUuid &ruleId)
|
|||
void RuleManager::editRule(Rule *rule)
|
||||
{
|
||||
QVariantMap params = JsonTypes::packRule(rule);
|
||||
qWarning() << "Packed rule:" << params;
|
||||
m_jsonClient->sendCommand("Rules.EditRule", params, this, "onEditRuleReply");
|
||||
|
||||
}
|
||||
|
|
@ -97,7 +99,8 @@ void RuleManager::handleRulesNotification(const QVariantMap ¶ms)
|
|||
}
|
||||
m_rules->remove(ruleId);
|
||||
m_rules->insert(parseRule(ruleMap));
|
||||
|
||||
} else if (params.value("notification").toString() == "Rules.RuleActiveChanged") {
|
||||
m_rules->getRule(params.value("params").toMap().value("ruleId").toUuid())->setActive(params.value("params").toMap().value("active").toBool());
|
||||
} else {
|
||||
qWarning() << "Unhandled rule notification" << params;
|
||||
}
|
||||
|
|
@ -113,10 +116,12 @@ void RuleManager::getRulesReply(const QVariantMap ¶ms)
|
|||
QUuid ruleId = ruleDescriptionVariant.toMap().value("id").toUuid();
|
||||
QString name = ruleDescriptionVariant.toMap().value("name").toString();
|
||||
bool enabled = ruleDescriptionVariant.toMap().value("enabled").toBool();
|
||||
bool active = ruleDescriptionVariant.toMap().value("active").toBool();
|
||||
|
||||
Rule *rule = new Rule(ruleId, m_rules);
|
||||
rule->setName(name);
|
||||
rule->setEnabled(enabled);
|
||||
rule->setActive(active);
|
||||
m_rules->insert(rule);
|
||||
|
||||
QVariantMap requestParams;
|
||||
|
|
@ -136,7 +141,8 @@ void RuleManager::getRuleDetailsReply(const QVariantMap ¶ms)
|
|||
qDebug() << "got rule details for rule" << ruleMap;
|
||||
parseEventDescriptors(ruleMap.value("eventDescriptors").toList(), rule);
|
||||
parseRuleActions(ruleMap.value("actions").toList(), rule);
|
||||
parseStateEvaluator(ruleMap.value("stateEvaluator").toMap());
|
||||
parseRuleExitActions(ruleMap.value("exitActions").toList(), rule);
|
||||
rule->setStateEvaluator(parseStateEvaluator(ruleMap.value("stateEvaluator").toMap()));
|
||||
}
|
||||
|
||||
void RuleManager::onAddRuleReply(const QVariantMap ¶ms)
|
||||
|
|
@ -167,9 +173,9 @@ Rule *RuleManager::parseRule(const QVariantMap &ruleMap)
|
|||
rule->setEnabled(enabled);
|
||||
rule->setActive(active);
|
||||
parseEventDescriptors(ruleMap.value("eventDescriptors").toList(), rule);
|
||||
StateEvaluator* stateEvaluator = parseStateEvaluator(ruleMap.value("stateEvaluator").toMap());
|
||||
stateEvaluator->setParent(rule);
|
||||
parseRuleActions(ruleMap.value("actions").toList(), rule);
|
||||
parseRuleExitActions(ruleMap.value("exitActions").toList(), rule);
|
||||
rule->setStateEvaluator(parseStateEvaluator(ruleMap.value("stateEvaluator").toMap()));
|
||||
return rule;
|
||||
}
|
||||
|
||||
|
|
@ -193,28 +199,21 @@ void RuleManager::parseEventDescriptors(const QVariantList &eventDescriptorList,
|
|||
|
||||
StateEvaluator *RuleManager::parseStateEvaluator(const QVariantMap &stateEvaluatorMap)
|
||||
{
|
||||
qDebug() << "bla" << stateEvaluatorMap;
|
||||
StateEvaluator *stateEvaluator = new StateEvaluator(this);
|
||||
if (stateEvaluatorMap.contains("stateDescriptor")) {
|
||||
QVariantMap sdMap = stateEvaluatorMap.value("sateDescriptor").toMap();
|
||||
QString operatorString = sdMap.value("stateOperator").toString();
|
||||
StateDescriptor::ValueOperator op;
|
||||
if (operatorString == "ValueOperatorEquals") {
|
||||
op = StateDescriptor::ValueOperatorEquals;
|
||||
} else if (operatorString == "ValueOperatorNotEquals") {
|
||||
op = StateDescriptor::ValueOperatorNotEquals;
|
||||
} else if (operatorString == "ValueOperatorLess") {
|
||||
op = StateDescriptor::ValueOperatorLess;
|
||||
} else if (operatorString == "ValueOperatorGreater") {
|
||||
op = StateDescriptor::ValueOperatorGreater;
|
||||
} else if (operatorString == "ValueOperatorLessOrEqual") {
|
||||
op = StateDescriptor::ValueOperatorLessOrEqual;
|
||||
} else if (operatorString == "ValueOperatorGreaterOrEqual") {
|
||||
op = StateDescriptor::ValueOperatorGreaterOrEqual;
|
||||
}
|
||||
QVariantMap sdMap = stateEvaluatorMap.value("stateDescriptor").toMap();
|
||||
QMetaEnum operatorEnum = QMetaEnum::fromType<StateDescriptor::ValueOperator>();
|
||||
StateDescriptor::ValueOperator op = (StateDescriptor::ValueOperator)operatorEnum.keyToValue(sdMap.value("operator").toByteArray());
|
||||
StateDescriptor *sd = new StateDescriptor(sdMap.value("deviceId").toUuid(), op, sdMap.value("stateTypeId").toUuid(), sdMap.value("value"), stateEvaluator);
|
||||
stateEvaluator->setStateDescriptor(sd);
|
||||
|
||||
}
|
||||
|
||||
foreach (const QVariant &childEvaluatorVariant, stateEvaluatorMap.value("childEvaluators").toList()) {
|
||||
stateEvaluator->childEvaluators()->addStateEvaluator(parseStateEvaluator(childEvaluatorVariant.toMap()));
|
||||
}
|
||||
QMetaEnum operatorEnum = QMetaEnum::fromType<StateEvaluator::StateOperator>();
|
||||
stateEvaluator->setStateOperator((StateEvaluator::StateOperator)operatorEnum.keyToValue(stateEvaluatorMap.value("operator").toByteArray()));
|
||||
return stateEvaluator;
|
||||
}
|
||||
|
||||
|
|
@ -230,6 +229,22 @@ void RuleManager::parseRuleActions(const QVariantList &ruleActions, Rule *rule)
|
|||
param->setValue(ruleActionParamVariant.toMap().value("value"));
|
||||
ruleAction->ruleActionParams()->addRuleActionParam(param);
|
||||
}
|
||||
rule->ruleActions()->addRuleAction(ruleAction);
|
||||
rule->actions()->addRuleAction(ruleAction);
|
||||
}
|
||||
}
|
||||
|
||||
void RuleManager::parseRuleExitActions(const QVariantList &ruleActions, Rule *rule)
|
||||
{
|
||||
foreach (const QVariant &ruleActionVariant, ruleActions) {
|
||||
RuleAction *ruleAction = new RuleAction();
|
||||
ruleAction->setDeviceId(ruleActionVariant.toMap().value("deviceId").toUuid());
|
||||
ruleAction->setActionTypeId(ruleActionVariant.toMap().value("actionTypeId").toUuid());
|
||||
foreach (const QVariant &ruleActionParamVariant, ruleActionVariant.toMap().value("ruleActionParams").toList()) {
|
||||
RuleActionParam *param = new RuleActionParam();
|
||||
param->setParamTypeId(ruleActionParamVariant.toMap().value("paramTypeId").toUuid());
|
||||
param->setValue(ruleActionParamVariant.toMap().value("value"));
|
||||
ruleAction->ruleActionParams()->addRuleActionParam(param);
|
||||
}
|
||||
rule->exitActions()->addRuleAction(ruleAction);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ private:
|
|||
void parseEventDescriptors(const QVariantList &eventDescriptorList, Rule *rule);
|
||||
StateEvaluator* parseStateEvaluator(const QVariantMap &stateEvaluatorMap);
|
||||
void parseRuleActions(const QVariantList &ruleActions, Rule *rule);
|
||||
void parseRuleExitActions(const QVariantList &ruleActions, Rule *rule);
|
||||
|
||||
signals:
|
||||
void addRuleReply(const QString &ruleError);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ TcpSocketInterface::TcpSocketInterface(QObject *parent) : GuhInterface(parent)
|
|||
|
||||
QStringList TcpSocketInterface::supportedSchemes() const
|
||||
{
|
||||
return {"guh", "guhs"};
|
||||
return {"nymea", "nymeas"};
|
||||
}
|
||||
|
||||
void TcpSocketInterface::sendData(const QByteArray &data)
|
||||
|
|
@ -31,7 +31,7 @@ void TcpSocketInterface::ignoreSslErrors(const QList<QSslError> &errors)
|
|||
|
||||
void TcpSocketInterface::onConnected()
|
||||
{
|
||||
if (m_url.scheme() == "guh") {
|
||||
if (m_url.scheme() == "nymea") {
|
||||
qDebug() << "TCP socket connected";
|
||||
emit connected();
|
||||
}
|
||||
|
|
@ -46,10 +46,10 @@ void TcpSocketInterface::onEncrypted()
|
|||
void TcpSocketInterface::connect(const QUrl &url)
|
||||
{
|
||||
m_url = url;
|
||||
if (url.scheme() == "guhs") {
|
||||
if (url.scheme() == "nymeas") {
|
||||
qDebug() << "connecting to" << url.host() << url.port();
|
||||
m_socket.connectToHostEncrypted(url.host(), url.port());
|
||||
} else if (url.scheme() == "guh") {
|
||||
} else if (url.scheme() == "nymea") {
|
||||
m_socket.connectToHost(url.host(), url.port());
|
||||
} else {
|
||||
qWarning() << "Unsupported scheme";
|
||||
|
|
|
|||
|
|
@ -130,11 +130,26 @@ Page {
|
|||
Component {
|
||||
id: connectingPage
|
||||
Page {
|
||||
Label {
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
width: parent.width - app.margins * 2
|
||||
text: "Connecting to your guh box..."
|
||||
font.pixelSize: app.largeFont
|
||||
spacing: app.margins
|
||||
|
||||
Label {
|
||||
text: qsTr("Connecting to your guh box...")
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: app.largeFont
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "Cancel"
|
||||
Layout.fillWidth: true
|
||||
onClicked: {
|
||||
Engine.connection.disconnect()
|
||||
pageStack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,287 @@
|
|||
import QtQuick 2.8
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Controls.Material 2.1
|
||||
import Guh 1.0
|
||||
import "../components"
|
||||
|
||||
ItemDelegate {
|
||||
id: root
|
||||
|
||||
property var actionType: null
|
||||
property var actionState: null
|
||||
|
||||
signal executeAction(var params)
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
RowLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: root.actionType.displayName
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Loader {
|
||||
id: loader
|
||||
Layout.fillWidth: sourceComponent == textFieldComponent
|
||||
sourceComponent: {
|
||||
if (root.actionType.paramTypes.count !== 1) {
|
||||
return buttonComponent
|
||||
}
|
||||
|
||||
var paramType = root.actionType.paramTypes.get(0);
|
||||
switch (paramType.type.toLowerCase()) {
|
||||
case "bool":
|
||||
return boolComponent;
|
||||
case "int":
|
||||
return stringComponent;
|
||||
case "string":
|
||||
case "qstring":
|
||||
if (paramType.allowedValues.length > 0) {
|
||||
return comboBoxComponent;
|
||||
}
|
||||
return textFieldComponent;
|
||||
case "color":
|
||||
return colorPreviewComponent;
|
||||
}
|
||||
console.warn("Param Delegate: Fallback to stringComponent", paramType.name, paramType.type)
|
||||
return stringComponent;
|
||||
}
|
||||
}
|
||||
Binding {
|
||||
target: loader.item
|
||||
when: loader.item
|
||||
property: "paramType"
|
||||
value: root.actionType.paramTypes.get(0)
|
||||
}
|
||||
Binding {
|
||||
target: loader.item
|
||||
when: loader.item
|
||||
property: "value"
|
||||
value: root.actionState
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
id: paramRepeater
|
||||
model: root.actionType.paramTypes
|
||||
delegate: Loader {
|
||||
id: bottomLoader
|
||||
property var paramType: root.actionType.paramTypes.get(index)
|
||||
Layout.fillWidth: true
|
||||
sourceComponent: {
|
||||
switch (paramType.type.toLowerCase()) {
|
||||
case "int":
|
||||
case "double":
|
||||
if (paramType.minValue != undefined && paramType.maxValue != undefined) {
|
||||
return sliderComponent
|
||||
}
|
||||
break;
|
||||
case "color":
|
||||
return colorPickerComponent
|
||||
case "string":
|
||||
return paramType.allowedValues.length === 0 ? textFieldComponent : null
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: bottomLoader.item
|
||||
when: bottomLoader.item
|
||||
property: "paramType"
|
||||
value: bottomLoader.paramType
|
||||
}
|
||||
Binding {
|
||||
target: bottomLoader.item
|
||||
when: bottomLoader.item && root.actionState
|
||||
property: "value"
|
||||
value: root.actionState
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: stringComponent
|
||||
Label {
|
||||
property var paramType: null
|
||||
property var value: null
|
||||
text: {
|
||||
switch (paramType.type.toLowerCase()) {
|
||||
case "int":
|
||||
return Math.round(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: boolComponent
|
||||
Switch {
|
||||
checked: root.actionState === true
|
||||
onClicked: {
|
||||
var params = [];
|
||||
var param1 = new Object();
|
||||
param1["paramTypeId"] = root.actionType.paramTypes.get(0).id;
|
||||
param1["value"] = checked;
|
||||
params.push(param1)
|
||||
root.executeAction(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: sliderComponent
|
||||
RowLayout {
|
||||
id: sliderRow
|
||||
spacing: app.margins
|
||||
property var paramType: null
|
||||
property var value: null
|
||||
Label {
|
||||
text: sliderRow.paramType.minValue
|
||||
}
|
||||
Slider {
|
||||
Layout.fillWidth: true
|
||||
from: sliderRow.paramType.minValue
|
||||
to: sliderRow.paramType.maxValue
|
||||
value: sliderRow.value
|
||||
stepSize: {
|
||||
switch (sliderRow.paramType.type) {
|
||||
case "Int":
|
||||
return 1;
|
||||
}
|
||||
return 0.01;
|
||||
|
||||
}
|
||||
|
||||
onValueChanged: {
|
||||
if (pressed) {
|
||||
var params = [];
|
||||
var param1 = new Object();
|
||||
param1["paramTypeId"] = sliderRow.paramType.id;
|
||||
param1["value"] = value;
|
||||
params.push(param1)
|
||||
root.executeAction(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
Label {
|
||||
text: sliderRow.paramType.maxValue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Component {
|
||||
id: textFieldComponent
|
||||
RowLayout {
|
||||
property alias value: textField.text
|
||||
property var paramType: null
|
||||
spacing: app.margins
|
||||
Label {
|
||||
text: paramType.displayName
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: textField
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: comboBoxComponent
|
||||
ComboBox {
|
||||
id: box
|
||||
model: paramType.allowedValues
|
||||
currentIndex: paramType.allowedValues.indexOf(value)
|
||||
property var paramType: null
|
||||
property var value: null
|
||||
onActivated: {
|
||||
value = paramType.allowedValues[index]
|
||||
var params = [];
|
||||
var param1 = new Object();
|
||||
param1["paramTypeId"] = paramType.id;
|
||||
param1["value"] = currentText;
|
||||
params.push(param1)
|
||||
root.executeAction(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: colorPickerComponent
|
||||
ColorPicker {
|
||||
id: colorPicker
|
||||
implicitHeight: 200
|
||||
// color: root.param.value
|
||||
|
||||
Binding {
|
||||
target: colorPicker
|
||||
property: "color"
|
||||
value: root.actionState
|
||||
when: !colorPicker.pressed
|
||||
}
|
||||
|
||||
property var lastSentTime: new Date()
|
||||
onColorChanged: {
|
||||
var currentTime = new Date();
|
||||
if (pressed && currentTime - lastSentTime > 200) {
|
||||
var params = [];
|
||||
var param1 = new Object();
|
||||
param1["paramTypeId"] = paramType.id;
|
||||
param1["value"] = color;
|
||||
params.push(param1)
|
||||
root.executeAction(params)
|
||||
}
|
||||
}
|
||||
|
||||
touchDelegate: Rectangle {
|
||||
height: 15
|
||||
width: height
|
||||
radius: height / 2
|
||||
color: Material.accent
|
||||
|
||||
|
||||
Rectangle {
|
||||
color: colorPicker.hovered || colorPicker.pressed ? "#11000000" : "transparent"
|
||||
anchors.centerIn: parent
|
||||
height: 30
|
||||
width: height
|
||||
radius: width / 2
|
||||
Behavior on color { ColorAnimation { duration: 200 } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: colorPreviewComponent
|
||||
Rectangle {
|
||||
property var paramType: null
|
||||
property var value: null
|
||||
implicitHeight: app.mediumFont
|
||||
implicitWidth: implicitHeight
|
||||
color: value
|
||||
radius: width / 4
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: buttonComponent
|
||||
Button {
|
||||
// just to suppress some warnings
|
||||
property var paramType: null
|
||||
property var value: null
|
||||
text: "Do it"
|
||||
onClicked: {
|
||||
var params = [];
|
||||
for (var i = 0; i < root.actionType.paramTypes.count; i++) {
|
||||
var param = new Object();
|
||||
param["paramTypeId"] = root.actionType.paramTypes.get(i).id;
|
||||
param["value"] = paramRepeater.itemAt(i).item.value;
|
||||
params.push(param)
|
||||
}
|
||||
|
||||
root.executeAction(params)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,10 @@ Page {
|
|||
return qsTr("All my things")
|
||||
}
|
||||
|
||||
onBackPressed: pageStack.pop()
|
||||
onBackPressed: {
|
||||
print("popping")
|
||||
pageStack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
function enterPage(index, replace) {
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ Page {
|
|||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: model.name
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Slider {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ DevicePageBase {
|
|||
|
||||
header: GuhHeader {
|
||||
text: device.name
|
||||
onBackPressed: pageStack.pop()
|
||||
onBackPressed: {
|
||||
print("popping")
|
||||
pageStack.pop()
|
||||
}
|
||||
|
||||
HeaderButton {
|
||||
imageSource: "../images/info.svg"
|
||||
|
|
@ -34,11 +37,11 @@ DevicePageBase {
|
|||
model: RulesFilterModel {
|
||||
id: rulesFilterModel
|
||||
rules: Engine.ruleManager.rules
|
||||
filterEventDeviceId: root.device.id
|
||||
filterDeviceId: root.device.id
|
||||
}
|
||||
delegate: SwipeDelegate {
|
||||
width: parent.width
|
||||
property var ruleActions: rulesFilterModel.get(index).ruleActions
|
||||
property var ruleActions: rulesFilterModel.get(index).actions
|
||||
property var ruleAction: ruleActions.count == 1 ? ruleActions.get(0) : null
|
||||
property var ruleActionType: ruleAction ? ruleActionDeviceClass.actionTypes.getActionType(ruleAction.actionTypeId) : null
|
||||
property var ruleActionDevice: ruleAction ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import QtQuick 2.5
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.1
|
||||
import QtQuick.Controls.Material 2.1
|
||||
import Guh 1.0
|
||||
import "../components"
|
||||
import "../actiondelegates"
|
||||
|
||||
DevicePageBase {
|
||||
id: root
|
||||
|
|
@ -116,23 +116,55 @@ DevicePageBase {
|
|||
|
||||
}
|
||||
|
||||
ActionDelegateColor {
|
||||
ColorPicker {
|
||||
id: colorPicker
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
actionType: root.deviceClass.actionTypes.findByName("color")
|
||||
actionState: actionType ? root.device.states.getState(actionType.id).value : null
|
||||
Layout.margins: app.margins
|
||||
property var actionType: root.deviceClass.actionTypes.findByName("color")
|
||||
property var 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)
|
||||
color: actionState ? actionState : "white"
|
||||
touchDelegate: Rectangle {
|
||||
height: 15
|
||||
width: height
|
||||
radius: height / 2
|
||||
color: Material.accent
|
||||
|
||||
Rectangle {
|
||||
color: colorPicker.hovered || colorPicker.pressed ? "#11000000" : "transparent"
|
||||
anchors.centerIn: parent
|
||||
height: 30
|
||||
width: height
|
||||
radius: width / 2
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property var lastSentTime: new Date()
|
||||
onColorChanged: {
|
||||
var currentTime = new Date();
|
||||
if (pressed && currentTime - lastSentTime > 200) {
|
||||
var params = [];
|
||||
var param1 = new Object();
|
||||
param1["paramTypeId"] = actionType.paramTypes.get(0).id;
|
||||
param1["value"] = color;
|
||||
params.push(param1)
|
||||
Engine.deviceManager.executeAction(root.device.id, actionType.id, params)
|
||||
lastSentTime = currentTime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredHeight: 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ DevicePageBase {
|
|||
print("have actionType param:", actionType.paramTypes.get(i).name, actionType.paramTypes.get(i).type)
|
||||
}
|
||||
|
||||
return Qt.resolvedUrl("../actiondelegates-ng/ActionDelegate.qml");
|
||||
var delegate = "ActionDelegateFallback.qml";
|
||||
if (actionType.paramTypes.count === 0) {
|
||||
delegate = "ActionDelegateNoParams.qml";
|
||||
|
|
@ -117,7 +118,10 @@ DevicePageBase {
|
|||
} else if (paramType.type === "String" && paramType.allowedValues.length > 0) {
|
||||
delegate = "ActionDelegateStringFromStringList.qml";
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return Qt.resolvedUrl("../actiondelegates/" + delegate);
|
||||
}
|
||||
|
||||
|
|
@ -136,7 +140,7 @@ DevicePageBase {
|
|||
Connections {
|
||||
target: delegateLoader.item ? delegateLoader.item : null
|
||||
onExecuteAction: {
|
||||
delegateLoader.commandId = Engine.deviceManager.executeAction(root.device.id, model.id, params)
|
||||
Engine.deviceManager.executeAction(root.device.id, model.id, params)
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ Page {
|
|||
|
||||
onAccept: busyOverlay.opacity = 1
|
||||
|
||||
readonly property bool isStateBased: rule.eventDescriptors.count === 0
|
||||
readonly property bool actionsVisible: rule.eventDescriptors.count > 0 || rule.stateEvaluator !== null
|
||||
readonly property bool exitActionsVisible: actionsVisible && isStateBased
|
||||
readonly property bool hasExitActions: rule.exitActions.count > 0
|
||||
|
||||
function addEventDescriptor() {
|
||||
var eventDescriptor = root.rule.eventDescriptors.createNewEventDescriptor();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
|
|
@ -36,27 +41,51 @@ Page {
|
|||
})
|
||||
}
|
||||
|
||||
function addRuleAction() {
|
||||
var ruleAction = root.rule.ruleActions.createNewRuleAction();
|
||||
function editStateEvaluator() {
|
||||
print("opening page", root.rule.stateEvaluator)
|
||||
var page = pageStack.push(Qt.resolvedUrl("EditStateEvaluatorPage.qml"), { stateEvaluator: root.rule.stateEvaluator })
|
||||
}
|
||||
|
||||
function addAction() {
|
||||
var ruleAction = root.rule.actions.createNewRuleAction();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.onBackPressed.connect(function() { pageStack.pop() })
|
||||
page.onThingSelected.connect(function(device) {
|
||||
print("thing selected", device.name, device.id)
|
||||
ruleAction.deviceId = device.id;
|
||||
selectRuleActionData(ruleAction)
|
||||
selectRuleActionData(root.rule.actions, ruleAction)
|
||||
})
|
||||
page.onInterfaceSelected.connect(function(interfaceName) {
|
||||
print("interface selected", interfaceName)
|
||||
ruleAction.interfaceName = interfaceName;
|
||||
selectRuleActionData(ruleAction)
|
||||
selectRuleActionData(root.rule.actions, ruleAction)
|
||||
})
|
||||
}
|
||||
function selectRuleActionData(ruleAction) {
|
||||
function addExitAction() {
|
||||
var ruleAction = root.rule.exitActions.createNewRuleAction();
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.onBackPressed.connect(function() { pageStack.pop() })
|
||||
page.onThingSelected.connect(function(device) {
|
||||
print("thing selected", device.name, device.id)
|
||||
ruleAction.deviceId = device.id;
|
||||
selectRuleActionData(root.rule.exitActions, ruleAction)
|
||||
})
|
||||
page.onInterfaceSelected.connect(function(interfaceName) {
|
||||
print("interface selected", interfaceName)
|
||||
ruleAction.interfaceName = interfaceName;
|
||||
selectRuleActionData(root.rule.exitActions, ruleAction)
|
||||
})
|
||||
}
|
||||
|
||||
function selectRuleActionData(ruleActions, ruleAction) {
|
||||
print("opening with ruleAction", ruleAction)
|
||||
var ruleActionPage = pageStack.push(Qt.resolvedUrl("SelectRuleActionPage.qml"), {text: "Select action", ruleAction: ruleAction });
|
||||
ruleActionPage.onBackPressed.connect(function() {
|
||||
ruleAction.destroy();
|
||||
pageStack.pop(root);
|
||||
ruleAction.destroy();
|
||||
})
|
||||
ruleActionPage.onDone.connect(function() {
|
||||
root.rule.ruleActions.addRuleAction(ruleAction)
|
||||
ruleActions.addRuleAction(ruleAction)
|
||||
pageStack.pop(root);
|
||||
})
|
||||
}
|
||||
|
|
@ -111,18 +140,19 @@ Page {
|
|||
}
|
||||
}
|
||||
|
||||
ThinDivider {}
|
||||
ThinDivider { visible: !root.hasExitActions }
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
font.pixelSize: app.mediumFont
|
||||
text: "Events triggering this rule"
|
||||
visible: !root.hasExitActions
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: eventsRepeater
|
||||
model: root.rule.eventDescriptors
|
||||
model: root.hasExitActions ? null : root.rule.eventDescriptors
|
||||
delegate: SwipeDelegate {
|
||||
id: eventDelegate
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -174,9 +204,7 @@ Page {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
swipe.right: MouseArea {
|
||||
height: eventDelegate.height
|
||||
|
|
@ -198,24 +226,52 @@ Page {
|
|||
Layout.margins: app.margins
|
||||
text: eventsRepeater.count == 0 ? "Add an event..." : "Add another event..."
|
||||
onClicked: root.addEventDescriptor();
|
||||
visible: !root.hasExitActions
|
||||
}
|
||||
|
||||
ThinDivider {}
|
||||
|
||||
Label {
|
||||
text: "Actions to execute"
|
||||
text: "Conditions to be met"
|
||||
font.pixelSize: app.mediumFont
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
}
|
||||
|
||||
StateEvaluatorDelegate {
|
||||
Layout.fillWidth: true
|
||||
stateEvaluator: root.rule.stateEvaluator
|
||||
visible: root.rule.stateEvaluator !== null
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
text: "Add a condition"
|
||||
visible: root.rule.stateEvaluator === null
|
||||
onClicked: {
|
||||
root.rule.createStateEvaluator();
|
||||
// root.editStateEvaluator()
|
||||
}
|
||||
}
|
||||
|
||||
ThinDivider { visible: root.actionsVisible }
|
||||
|
||||
Label {
|
||||
text: root.isStateBased ? "Active state enter actions" : "Actions to execute"
|
||||
font.pixelSize: app.mediumFont
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
visible: root.actionsVisible
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: actionsRepeater
|
||||
model: root.rule.ruleActions
|
||||
model: root.actionsVisible ? root.rule.actions : null
|
||||
delegate: SwipeDelegate {
|
||||
id: actionDelegate
|
||||
Layout.fillWidth: true
|
||||
property var ruleAction: root.rule.ruleActions.get(index)
|
||||
property var ruleAction: root.rule.actions.get(index)
|
||||
property var device: ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
property var iface: ruleAction.interfaceName ? Interfaces.findByName(ruleAction.interfaceName) : null
|
||||
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
|
|
@ -249,7 +305,7 @@ Page {
|
|||
name: "../images/delete.svg"
|
||||
color: "red"
|
||||
}
|
||||
onClicked: root.rule.ruleActions.removeRuleAction(index)
|
||||
onClicked: root.rule.actions.removeRuleAction(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -258,7 +314,72 @@ Page {
|
|||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
text: actionsRepeater.count == 0 ? "Add an action..." : "Add another action..."
|
||||
onClicked: root.addRuleAction();
|
||||
onClicked: root.addAction();
|
||||
visible: root.actionsVisible
|
||||
}
|
||||
|
||||
ThinDivider { visible: root.exitActionsVisible }
|
||||
|
||||
Label {
|
||||
text: "Active state exit actions"
|
||||
font.pixelSize: app.mediumFont
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
visible: root.exitActionsVisible
|
||||
}
|
||||
|
||||
|
||||
Repeater {
|
||||
id: exitActionsRepeater
|
||||
model: root.exitActionsVisible ? root.rule.exitActions : null
|
||||
delegate: SwipeDelegate {
|
||||
id: exitActionDelegate
|
||||
Layout.fillWidth: true
|
||||
property var ruleAction: root.rule.exitActions.get(index)
|
||||
property var device: ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
property var iface: ruleAction.interfaceName ? Interfaces.findByName(ruleAction.interfaceName) : null
|
||||
property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
property var actionType: deviceClass ? deviceClass.actionTypes.getActionType(ruleAction.actionTypeId)
|
||||
: iface ? iface.actionTypes.findByName(ruleAction.interfaceAction) : null
|
||||
contentItem: ColumnLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("%1 - %2").arg(exitActionDelegate.device ? exitActionDelegate.device.name : exitActionDelegate.iface.displayName).arg(exitActionDelegate.actionType.displayName)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: app.margins
|
||||
Repeater {
|
||||
model: exitActionDelegate.ruleAction.ruleActionParams
|
||||
Label {
|
||||
text: exitActionDelegate.actionType.paramTypes.getParamType(model.paramTypeId).displayName + " -> " + model.value
|
||||
font.pixelSize: app.smallFont
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
swipe.right: MouseArea {
|
||||
height: exitActionDelegate.height
|
||||
width: height
|
||||
anchors.right: parent.right
|
||||
ColorIcon {
|
||||
anchors.fill: parent
|
||||
anchors.margins: app.margins
|
||||
name: "../images/delete.svg"
|
||||
color: "red"
|
||||
}
|
||||
onClicked: root.rule.exitActions.removeRuleAction(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
text: actionsRepeater.count == 0 ? "Add an action..." : "Add another action..."
|
||||
onClicked: root.addExitAction();
|
||||
visible: root.exitActionsVisible
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import Guh 1.0
|
||||
import "../components"
|
||||
|
||||
Page {
|
||||
id: root
|
||||
header: GuhHeader {
|
||||
text: "Conditions"
|
||||
onBackPressed: pageStack.pop()
|
||||
}
|
||||
|
||||
property var stateEvaluator: null
|
||||
|
||||
StateEvaluatorDelegate {
|
||||
width: parent.width
|
||||
stateEvaluator: root.stateEvaluator
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ import QtQuick.Controls 2.1
|
|||
import QtQuick.Layouts 1.1
|
||||
import Guh 1.0
|
||||
import "../components"
|
||||
import "../actiondelegates"
|
||||
import "../paramdelegates"
|
||||
|
||||
Page {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ Page {
|
|||
|
||||
HeaderButton {
|
||||
imageSource: header.interfacesMode ? "../images/view-expand.svg" : "../images/view-collapse.svg"
|
||||
visible: root.ruleAction.interfaceName === ""
|
||||
visible: root.ruleAction.deviceId || root.ruleAction.interfaceName === ""
|
||||
onClicked: header.interfacesMode = !header.interfacesMode
|
||||
}
|
||||
}
|
||||
|
|
@ -50,8 +50,8 @@ Page {
|
|||
if (header.interfacesMode) {
|
||||
if (root.device) {
|
||||
for (var i = 0; i < Interfaces.count; i++) {
|
||||
if (deviceClass.interfaces.indexOf(actionTemplateModel.get(i).interfaceName) >= 0) {
|
||||
actualModel.append(actionTemplateModel.get(i))
|
||||
if (deviceClass.interfaces.indexOf(Interfaces.get(i).interfaceName) >= 0) {
|
||||
actualModel.append(Interfaces.get(i))
|
||||
}
|
||||
}
|
||||
} else if (root.ruleAction.interfaceName !== "") {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import Guh 1.0
|
|||
|
||||
Page {
|
||||
id: root
|
||||
// Needs to be set and filled in with deviceId and actionTypeId
|
||||
// Needs to be set and filled in with deviceId and actionTypeId or interfaceName and interfaceAction
|
||||
property var ruleAction
|
||||
|
||||
readonly property var device: ruleAction && ruleAction.deviceId ? Engine.deviceManager.devices.getDevice(ruleAction.deviceId) : null
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import QtQuick 2.4
|
||||
import QtQuick.Controls 2.1
|
||||
import "../components"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
property alias text: header.text
|
||||
|
||||
// a ruleAction object needs to be set and prefilled with either deviceId or interfaceName
|
||||
property var stateDescriptor: null
|
||||
|
||||
readonly property var device: stateDescriptor && stateDescriptor.deviceId ? Engine.deviceManager.devices.getDevice(stateDescriptor.deviceId) : null
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
|
||||
signal backPressed();
|
||||
signal done();
|
||||
|
||||
header: GuhHeader {
|
||||
id: header
|
||||
onBackPressed: root.backPressed();
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listView
|
||||
anchors.fill: parent
|
||||
model: root.deviceClass.stateTypes
|
||||
|
||||
delegate: ItemDelegate {
|
||||
text: model.displayName
|
||||
width: parent.width
|
||||
onClicked: {
|
||||
var stateType = root.deviceClass.stateTypes.getStateType(model.id);
|
||||
console.log("StateType", stateType.id, "selected.")
|
||||
root.stateDescriptor.stateTypeId = stateType.id;
|
||||
var paramsPage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorParamsPage.qml"), {stateDescriptor: root.stateDescriptor})
|
||||
paramsPage.onBackPressed.connect(function() { pageStack.pop(); });
|
||||
paramsPage.onCompleted.connect(function() {
|
||||
pageStack.pop();
|
||||
root.done();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import "../components"
|
||||
import "../paramdescriptordelegates"
|
||||
import Guh 1.0
|
||||
|
||||
Page {
|
||||
id: root
|
||||
// Needs to be set and filled in with deviceId and eventTypeId
|
||||
property var stateDescriptor: null
|
||||
|
||||
readonly property var device: stateDescriptor && stateDescriptor.deviceId ? Engine.deviceManager.devices.getDevice(stateDescriptor.deviceId) : null
|
||||
readonly property var stateType: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId).stateTypes.getStateType(stateDescriptor.stateTypeId) : null
|
||||
|
||||
signal backPressed();
|
||||
signal completed();
|
||||
|
||||
header: GuhHeader {
|
||||
text: "params"
|
||||
onBackPressed: root.backPressed();
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
ParamDescriptorDelegateBase {
|
||||
id: paramDelegate
|
||||
Layout.fillWidth: true
|
||||
paramType: root.stateType
|
||||
value: paramType.defaultValue
|
||||
}
|
||||
Button {
|
||||
text: "OK"
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: app.margins
|
||||
onClicked: {
|
||||
root.stateDescriptor.valueOperator = paramDelegate.operatorType
|
||||
root.stateDescriptor.value = paramDelegate.value
|
||||
root.completed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import Guh 1.0
|
||||
|
||||
SwipeDelegate {
|
||||
id: root
|
||||
Layout.fillWidth: true
|
||||
|
||||
property var stateEvaluator: null
|
||||
property bool showChilds: false
|
||||
|
||||
readonly property var device: stateEvaluator ? Engine.deviceManager.devices.getDevice(stateEvaluator.stateDescriptor.deviceId) : null
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property var stateType: deviceClass ? deviceClass.stateTypes.getStateType(stateEvaluator.stateDescriptor.stateTypeId) : null
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
border.color: "black"
|
||||
border.width: 1
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
property string operatorString: {
|
||||
switch (root.stateEvaluator.stateDescriptor.valueOperator) {
|
||||
case StateDescriptor.ValueOperatorEquals:
|
||||
return "=";
|
||||
case StateDescriptor.ValueOperatorNotEquals:
|
||||
return "!=";
|
||||
case StateDescriptor.ValueOperatorGreater:
|
||||
return ">";
|
||||
case StateDescriptor.ValueOperatorGreaterOrEqual:
|
||||
return ">=";
|
||||
case StateDescriptor.ValueOperatorLess:
|
||||
return "<";
|
||||
case StateDescriptor.ValueOperatorLessOrEqual:
|
||||
return "<=";
|
||||
}
|
||||
return "FIXME"
|
||||
}
|
||||
|
||||
text: {
|
||||
if (!root.device) {
|
||||
return qsTr("Press to edit condition")
|
||||
}
|
||||
return qsTr("%1: %2 %3 %4").arg(root.device.name).arg(root.stateType.displayName).arg(operatorString).arg(root.stateEvaluator.stateDescriptor.value)
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
model: root.showChilds ? root.stateEvaluator.childEvaluators : null
|
||||
delegate: Label {
|
||||
Layout.fillWidth: true
|
||||
property var stateEvaluator: root.stateEvaluator.childEvaluators.get(index)
|
||||
property var stateDescriptor: stateEvaluator.stateDescriptor
|
||||
readonly property var device: Engine.deviceManager.devices.getDevice(stateDescriptor.deviceId)
|
||||
readonly property var deviceClass: Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId)
|
||||
readonly property var stateType: deviceClass.stateTypes.getStateType(stateDescriptor.stateTypeId)
|
||||
|
||||
property string operatorString: {
|
||||
switch (stateDescriptor.valueOperator) {
|
||||
case StateDescriptor.ValueOperatorEquals:
|
||||
return "=";
|
||||
case StateDescriptor.ValueOperatorNotEquals:
|
||||
return "!=";
|
||||
case StateDescriptor.ValueOperatorGreater:
|
||||
return ">";
|
||||
case StateDescriptor.ValueOperatorGreaterOrEqual:
|
||||
return ">=";
|
||||
case StateDescriptor.ValueOperatorLess:
|
||||
return "<";
|
||||
case StateDescriptor.ValueOperatorLessOrEqual:
|
||||
return "<=";
|
||||
}
|
||||
return "FIXME"
|
||||
}
|
||||
text: qsTr("%1 %2: %3 %4 %5%6").arg(root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? "and" : "or").arg(device.name).arg(stateType.displayName).arg(operatorString).arg(stateDescriptor.value).arg(stateEvaluator.childEvaluators.count > 0 ? "..." : "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import QtQuick 2.8
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.2
|
||||
import Guh 1.0
|
||||
|
||||
SwipeDelegate {
|
||||
|
||||
id: root
|
||||
property var stateEvaluator: null
|
||||
readonly property var device: stateEvaluator ? Engine.deviceManager.devices.getDevice(stateEvaluator.stateDescriptor.deviceId) : null
|
||||
readonly property var deviceClass: device ? Engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) : null
|
||||
readonly property var stateType: deviceClass ? deviceClass.stateTypes.getStateType(stateEvaluator.stateDescriptor.stateTypeId) : null
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
SimpleStateEvaluatorDelegate {
|
||||
Layout.fillWidth: true
|
||||
stateEvaluator: root.stateEvaluator
|
||||
onClicked: {
|
||||
var page = pageStack.push(Qt.resolvedUrl("SelectThingPage.qml"));
|
||||
page.backPressed.connect(function() {pageStack.pop()})
|
||||
page.thingSelected.connect(function(device) {
|
||||
root.stateEvaluator.stateDescriptor.deviceId = device.id
|
||||
var statePage = pageStack.push(Qt.resolvedUrl("SelectStateDescriptorPage.qml"), {text: "Select state", stateDescriptor: root.stateEvaluator.stateDescriptor})
|
||||
statePage.backPressed.connect(function() {pageStack.pop()})
|
||||
statePage.done.connect(function() {pageStack.pop(); pageStack.pop()})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["and all of those", "or any of those"]
|
||||
currentIndex: root.stateEvaluator.stateOperator === StateEvaluator.StateOperatorAnd ? 0 : 1
|
||||
visible: root.stateEvaluator.childEvaluators.count > 0
|
||||
onActivated: {
|
||||
root.stateEvaluator.stateOperator = index == 0 ? StateEvaluator.StateOperatorAnd : StateEvaluator.StateOperatorOr
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.stateEvaluator.childEvaluators
|
||||
delegate: SimpleStateEvaluatorDelegate {
|
||||
Layout.fillWidth: true
|
||||
stateEvaluator: root.stateEvaluator.childEvaluators.get(index)
|
||||
showChilds: true
|
||||
onClicked: {
|
||||
pageStack.push(Qt.resolvedUrl("EditStateEvaluatorPage.qml"), {stateEvaluator: stateEvaluator})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.fillWidth: true
|
||||
text: "Add a condition"
|
||||
onClicked: {
|
||||
root.stateEvaluator.addChildEvaluator()
|
||||
// root.editStateEvaluator()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ Page {
|
|||
|
||||
Label {
|
||||
width: listView.column2Width
|
||||
text: "Device"
|
||||
text: "Thing"
|
||||
}
|
||||
Label {
|
||||
width: listView.column3Width
|
||||
|
|
@ -134,7 +134,7 @@ Page {
|
|||
|
||||
Label {
|
||||
width: listView.column2Width
|
||||
text: delegate.device.name
|
||||
text: model.source === LogEntry.LoggingSourceSystem ? "Nymea Server" : delegate.device.name
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
Label {
|
||||
|
|
@ -144,7 +144,7 @@ Page {
|
|||
case LogEntry.LoggingSourceStates:
|
||||
return delegate.deviceClass.stateTypes.getStateType(model.typeId).displayName;
|
||||
case LogEntry.LoggingSourceSystem:
|
||||
return "SYS";
|
||||
return model.loggingEventType === LogEntry.LoggingEventTypeActiveChange ? "Active changed" : "FIXME"
|
||||
case LogEntry.LoggingSourceActions:
|
||||
return delegate.deviceClass.actionTypes.getActionType(model.typeId).displayName;
|
||||
case LogEntry.LoggingSourceEvents:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ QList<ParamType *> ParamTypes::paramTypes()
|
|||
|
||||
ParamType *ParamTypes::get(int index) const
|
||||
{
|
||||
return m_paramTypes.at(index);
|
||||
if (index >= 0 && index < m_paramTypes.count()) {
|
||||
return m_paramTypes.at(index);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ParamType *ParamTypes::getParamType(const QString &id) const
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ Rule::Rule(const QUuid &id, QObject *parent) :
|
|||
QObject(parent),
|
||||
m_id(id),
|
||||
m_eventDescriptors(new EventDescriptors(this)),
|
||||
m_stateEvaluator(new StateEvaluator(this)),
|
||||
m_ruleActions(new RuleActions(this))
|
||||
// m_stateEvaluator(new StateEvaluator(this)),
|
||||
m_actions(new RuleActions(this)),
|
||||
m_exitActions(new RuleActions(this))
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -71,9 +72,29 @@ StateEvaluator *Rule::stateEvaluator() const
|
|||
return m_stateEvaluator;
|
||||
}
|
||||
|
||||
RuleActions *Rule::ruleActions() const
|
||||
RuleActions *Rule::actions() const
|
||||
{
|
||||
return m_ruleActions;
|
||||
return m_actions;
|
||||
}
|
||||
|
||||
RuleActions *Rule::exitActions() const
|
||||
{
|
||||
return m_exitActions;
|
||||
}
|
||||
|
||||
void Rule::setStateEvaluator(StateEvaluator *stateEvaluator)
|
||||
{
|
||||
if (m_stateEvaluator) {
|
||||
m_stateEvaluator->deleteLater();
|
||||
}
|
||||
m_stateEvaluator = stateEvaluator;
|
||||
m_stateEvaluator->setParent(this);
|
||||
emit stateEvaluatorChanged();
|
||||
}
|
||||
|
||||
void Rule::createStateEvaluator()
|
||||
{
|
||||
setStateEvaluator(new StateEvaluator(this));
|
||||
}
|
||||
|
||||
Rule *Rule::clone() const
|
||||
|
|
@ -89,8 +110,11 @@ Rule *Rule::clone() const
|
|||
// for (int i = 0; i < this->stateEvaluator()->childEvaluators()->rowCount(); i++) {
|
||||
// ret->stateEvaluator()->childEvaluators()->
|
||||
// }
|
||||
for (int i = 0; i < this->ruleActions()->rowCount(); i++) {
|
||||
ret->ruleActions()->addRuleAction(this->ruleActions()->get(i)->clone());
|
||||
for (int i = 0; i < this->actions()->rowCount(); i++) {
|
||||
ret->actions()->addRuleAction(this->actions()->get(i)->clone());
|
||||
}
|
||||
for (int i = 0; i < this->exitActions()->rowCount(); i++) {
|
||||
ret->exitActions()->addRuleAction(this->exitActions()->get(i)->clone());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,9 @@ class Rule : public QObject
|
|||
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
|
||||
Q_PROPERTY(bool active READ active NOTIFY activeChanged)
|
||||
Q_PROPERTY(EventDescriptors* eventDescriptors READ eventDescriptors CONSTANT)
|
||||
Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator CONSTANT)
|
||||
Q_PROPERTY(RuleActions* ruleActions READ ruleActions CONSTANT)
|
||||
Q_PROPERTY(StateEvaluator* stateEvaluator READ stateEvaluator NOTIFY stateEvaluatorChanged)
|
||||
Q_PROPERTY(RuleActions* actions READ actions CONSTANT)
|
||||
Q_PROPERTY(RuleActions* exitActions READ exitActions CONSTANT)
|
||||
public:
|
||||
explicit Rule(const QUuid &id = QUuid(), QObject *parent = nullptr);
|
||||
|
||||
|
|
@ -34,7 +35,12 @@ public:
|
|||
|
||||
EventDescriptors* eventDescriptors() const;
|
||||
StateEvaluator *stateEvaluator() const;
|
||||
RuleActions* ruleActions() const;
|
||||
RuleActions* actions() const;
|
||||
RuleActions* exitActions() const;
|
||||
|
||||
void setStateEvaluator(StateEvaluator* stateEvaluator);
|
||||
|
||||
Q_INVOKABLE void createStateEvaluator();
|
||||
|
||||
Rule *clone() const;
|
||||
|
||||
|
|
@ -42,6 +48,7 @@ signals:
|
|||
void nameChanged();
|
||||
void enabledChanged();
|
||||
void activeChanged();
|
||||
void stateEvaluatorChanged();
|
||||
|
||||
private:
|
||||
QUuid m_id;
|
||||
|
|
@ -50,7 +57,8 @@ private:
|
|||
bool m_active = false;
|
||||
EventDescriptors *m_eventDescriptors = nullptr;
|
||||
StateEvaluator *m_stateEvaluator = nullptr;
|
||||
RuleActions *m_ruleActions = nullptr;
|
||||
RuleActions *m_actions = nullptr;
|
||||
RuleActions *m_exitActions = nullptr;
|
||||
};
|
||||
|
||||
#endif // RULE_H
|
||||
|
|
|
|||
|
|
@ -10,26 +10,63 @@ StateDescriptor::StateDescriptor(const QUuid &deviceId, StateDescriptor::ValueOp
|
|||
|
||||
}
|
||||
|
||||
StateDescriptor::StateDescriptor(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QUuid StateDescriptor::deviceId() const
|
||||
{
|
||||
return m_deviceId;
|
||||
}
|
||||
|
||||
void StateDescriptor::setDeviceId(const QUuid &deviceId)
|
||||
{
|
||||
if (m_deviceId != deviceId) {
|
||||
m_deviceId = deviceId;
|
||||
emit deviceIdChanged();
|
||||
}
|
||||
}
|
||||
|
||||
StateDescriptor::ValueOperator StateDescriptor::valueOperator() const
|
||||
{
|
||||
return m_operator;
|
||||
}
|
||||
|
||||
void StateDescriptor::setValueOperator(StateDescriptor::ValueOperator valueOperator)
|
||||
{
|
||||
if (m_operator != valueOperator) {
|
||||
m_operator = valueOperator;
|
||||
emit valueOperatorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QUuid StateDescriptor::stateTypeId() const
|
||||
{
|
||||
return m_stateTypeId;
|
||||
}
|
||||
|
||||
void StateDescriptor::setStateTypeId(const QUuid &stateTypeId)
|
||||
{
|
||||
if (m_stateTypeId != stateTypeId) {
|
||||
m_stateTypeId = stateTypeId;
|
||||
emit stateTypeIdChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant StateDescriptor::value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
void StateDescriptor::setValue(const QVariant &value)
|
||||
{
|
||||
if (m_value != value) {
|
||||
m_value = value;
|
||||
emit valueChanged();
|
||||
}
|
||||
}
|
||||
|
||||
StateDescriptor *StateDescriptor::clone() const
|
||||
{
|
||||
StateDescriptor *ret = new StateDescriptor(deviceId(), valueOperator(), stateTypeId(), value());
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
class StateDescriptor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QUuid deviceId READ deviceId CONSTANT)
|
||||
Q_PROPERTY(ValueOperator valueOperator READ valueOperator CONSTANT)
|
||||
Q_PROPERTY(QUuid stateTypeId READ stateTypeId CONSTANT)
|
||||
Q_PROPERTY(QVariant value READ value CONSTANT)
|
||||
Q_PROPERTY(QUuid deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
|
||||
Q_PROPERTY(ValueOperator valueOperator READ valueOperator WRITE setValueOperator NOTIFY valueOperatorChanged)
|
||||
Q_PROPERTY(QUuid stateTypeId READ stateTypeId WRITE setStateTypeId NOTIFY stateTypeIdChanged)
|
||||
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
|
||||
|
||||
public:
|
||||
enum ValueOperator {
|
||||
|
|
@ -25,13 +25,28 @@ public:
|
|||
Q_ENUM(ValueOperator)
|
||||
|
||||
explicit StateDescriptor(const QUuid &deviceId, ValueOperator valueOperator, const QUuid &stateTypeId, const QVariant &value, QObject *parent = nullptr);
|
||||
StateDescriptor(QObject *parent = nullptr);
|
||||
|
||||
QUuid deviceId() const;
|
||||
void setDeviceId(const QUuid &deviceId);
|
||||
|
||||
ValueOperator valueOperator() const;
|
||||
void setValueOperator(ValueOperator valueOperator);
|
||||
|
||||
QUuid stateTypeId() const;
|
||||
void setStateTypeId(const QUuid &stateTypeId);
|
||||
|
||||
QVariant value() const;
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
StateDescriptor* clone() const;
|
||||
|
||||
signals:
|
||||
void deviceIdChanged();
|
||||
void valueOperatorChanged();
|
||||
void stateTypeIdChanged();
|
||||
void valueChanged();
|
||||
|
||||
private:
|
||||
QUuid m_deviceId;
|
||||
ValueOperator m_operator = ValueOperatorEquals;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
StateEvaluator::StateEvaluator(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_childEvaluators = new StateEvaluators(this);
|
||||
// m_stateDescriptor = new StateDescriptor(this);
|
||||
m_stateDescriptor = new StateDescriptor(this);
|
||||
}
|
||||
|
||||
StateEvaluator::StateOperator StateEvaluator::stateOperator() const
|
||||
|
|
@ -15,7 +15,10 @@ StateEvaluator::StateOperator StateEvaluator::stateOperator() const
|
|||
|
||||
void StateEvaluator::setStateOperator(StateEvaluator::StateOperator stateOperator)
|
||||
{
|
||||
m_operator = stateOperator;
|
||||
if (m_operator != stateOperator) {
|
||||
m_operator = stateOperator;
|
||||
emit stateOperatorChanged();
|
||||
}
|
||||
}
|
||||
|
||||
StateEvaluators *StateEvaluator::childEvaluators() const
|
||||
|
|
@ -49,3 +52,10 @@ bool StateEvaluator::containsDevice(const QUuid &deviceId) const
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
StateEvaluator* StateEvaluator::addChildEvaluator()
|
||||
{
|
||||
StateEvaluator* stateEvaluator = new StateEvaluator(m_childEvaluators);
|
||||
m_childEvaluators->addStateEvaluator(stateEvaluator);
|
||||
return stateEvaluator;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class StateDescriptor;
|
|||
class StateEvaluator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(StateOperator stateOperator READ stateOperator CONSTANT)
|
||||
Q_PROPERTY(StateOperator stateOperator READ stateOperator WRITE setStateOperator NOTIFY stateOperatorChanged)
|
||||
Q_PROPERTY(StateEvaluators* childEvaluators READ childEvaluators CONSTANT)
|
||||
Q_PROPERTY(StateDescriptor* stateDescriptor READ stateDescriptor CONSTANT)
|
||||
|
||||
|
|
@ -31,6 +31,11 @@ public:
|
|||
|
||||
bool containsDevice(const QUuid &deviceId) const;
|
||||
|
||||
Q_INVOKABLE StateEvaluator* addChildEvaluator();
|
||||
|
||||
signals:
|
||||
void stateOperatorChanged();
|
||||
|
||||
private:
|
||||
StateOperator m_operator = StateOperatorAnd;
|
||||
StateEvaluators *m_childEvaluators = nullptr;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,23 @@ QHash<int, QByteArray> StateEvaluators::roleNames() const
|
|||
return roles;
|
||||
}
|
||||
|
||||
void StateEvaluators::addStateEvaluator(StateEvaluator *stateEvaluator)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), m_list.count(), m_list.count());
|
||||
m_list.append(stateEvaluator);
|
||||
endInsertRows();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
StateEvaluator *StateEvaluators::get(int index) const
|
||||
{
|
||||
return m_list.at(index);
|
||||
}
|
||||
|
||||
StateEvaluator *StateEvaluators::take(int index)
|
||||
{
|
||||
beginRemoveRows(QModelIndex(), index, index);
|
||||
return m_list.takeAt(index);
|
||||
endInsertRows();
|
||||
emit countChanged();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ class StateEvaluator;
|
|||
class StateEvaluators : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
|
||||
public:
|
||||
explicit StateEvaluators(QObject *parent = nullptr);
|
||||
|
||||
|
|
@ -15,7 +17,13 @@ public:
|
|||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
StateEvaluator* get(int index) const;
|
||||
void addStateEvaluator(StateEvaluator* stateEvaluator);
|
||||
Q_INVOKABLE StateEvaluator* get(int index) const;
|
||||
StateEvaluator* take(int index);
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
|
||||
private:
|
||||
QList<StateEvaluator*> m_list;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue