mirror of https://github.com/nymea/nymea.git
more work... not really working yet
parent
56448543df
commit
ae38e185b6
|
|
@ -650,6 +650,14 @@ ThingPairingInfo *ThingManagerImplementation::confirmPairing(const PairingTransa
|
|||
ParamList settings = buildParams(thingClass.settingsTypes(), ParamList());
|
||||
thing->setSettings(settings);
|
||||
|
||||
QList<EventTypeId> loggedEventTypeIds;
|
||||
foreach (const EventType &eventType, thingClass.eventTypes()) {
|
||||
if (eventType.suggestLogging()) {
|
||||
loggedEventTypeIds.append(eventType.id());
|
||||
}
|
||||
}
|
||||
thing->setLoggedEventTypeIds(loggedEventTypeIds);
|
||||
|
||||
ThingSetupInfo *info = setupThing(thing);
|
||||
connect(info, &ThingSetupInfo::finished, thing, [this, info, externalInfo, addNewThing](){
|
||||
|
||||
|
|
@ -746,6 +754,14 @@ ThingSetupInfo* ThingManagerImplementation::addConfiguredThingInternal(const Thi
|
|||
ParamList settings = buildParams(thingClass.settingsTypes(), ParamList());
|
||||
thing->setSettings(settings);
|
||||
|
||||
QList<EventTypeId> loggedEventTypeIds;
|
||||
foreach (const EventType &eventType, thingClass.eventTypes()) {
|
||||
if (eventType.suggestLogging()) {
|
||||
loggedEventTypeIds.append(eventType.id());
|
||||
}
|
||||
}
|
||||
thing->setLoggedEventTypeIds(loggedEventTypeIds);
|
||||
|
||||
ThingSetupInfo *info = setupThing(thing);
|
||||
connect(info, &ThingSetupInfo::finished, this, [this, info](){
|
||||
if (info->status() != Thing::ThingErrorNoError) {
|
||||
|
|
@ -1258,6 +1274,10 @@ ThingActionInfo *ThingManagerImplementation::executeAction(const Action &action)
|
|||
return info;
|
||||
}
|
||||
|
||||
connect(info, &ThingActionInfo::finished, this, [=](){
|
||||
emit actionExecuted(action, info->status());
|
||||
});
|
||||
|
||||
plugin->executeAction(info);
|
||||
|
||||
return info;
|
||||
|
|
@ -1541,6 +1561,14 @@ void ThingManagerImplementation::loadConfiguredThings()
|
|||
|
||||
thing->setSettings(thingSettings);
|
||||
|
||||
QList<EventTypeId> loggedEventTypeIds;
|
||||
foreach (const EventType &eventType, thingClass.eventTypes()) {
|
||||
if (eventType.suggestLogging()) {
|
||||
loggedEventTypeIds.append(eventType.id());
|
||||
}
|
||||
}
|
||||
thing->setLoggedEventTypeIds(loggedEventTypeIds);
|
||||
|
||||
settings.endGroup(); // ThingId
|
||||
|
||||
// We always add the thing to the list in this case. If it's in the stored things
|
||||
|
|
@ -1659,6 +1687,14 @@ void ThingManagerImplementation::onAutoThingsAppeared(const ThingDescriptors &th
|
|||
thing->setSettings(settings);
|
||||
thing->setParentId(thingDescriptor.parentId());
|
||||
|
||||
QList<EventTypeId> loggedEventTypeIds;
|
||||
foreach (const EventType &eventType, thingClass.eventTypes()) {
|
||||
if (eventType.suggestLogging()) {
|
||||
loggedEventTypeIds.append(eventType.id());
|
||||
}
|
||||
}
|
||||
thing->setLoggedEventTypeIds(loggedEventTypeIds);
|
||||
|
||||
qCDebug(dcThingManager()) << "Setting up auto thing:" << thing->name() << thing->id().toString();
|
||||
|
||||
ThingSetupInfo *info = setupThing(thing);
|
||||
|
|
@ -1725,7 +1761,7 @@ void ThingManagerImplementation::cleanupThingStateCache()
|
|||
}
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::onEventTriggered(const Event &event)
|
||||
void ThingManagerImplementation::onEventTriggered(Event event)
|
||||
{
|
||||
// Doing some sanity checks here...
|
||||
Thing *thing = m_configuredThings.value(event.thingId());
|
||||
|
|
@ -1738,7 +1774,12 @@ void ThingManagerImplementation::onEventTriggered(const Event &event)
|
|||
qCWarning(dcThingManager()) << "The given thing does not have an event type of id " + event.eventTypeId().toString() + ". Not forwarding event.";
|
||||
return;
|
||||
}
|
||||
// All good, forward the event
|
||||
// configure logging
|
||||
if (thing->loggedEventTypeIds().contains(event.eventTypeId())) {
|
||||
event.setLogged(true);
|
||||
}
|
||||
|
||||
// Forward the event
|
||||
emit eventTriggered(event);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ private slots:
|
|||
void onAutoThingDisappeared(const ThingId &thingId);
|
||||
void onLoaded();
|
||||
void cleanupThingStateCache();
|
||||
void onEventTriggered(const Event &event);
|
||||
void onEventTriggered(Event event);
|
||||
|
||||
// Only connect this to Things. It will query the sender()
|
||||
void slotThingStateValueChanged(const StateTypeId &stateTypeId, const QVariant &value);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ JsonReply* ActionHandler::ExecuteAction(const QVariantMap ¶ms, const JsonCon
|
|||
|
||||
JsonReply *jsonReply = createAsyncReply("ExecuteAction");
|
||||
|
||||
ThingActionInfo *info = NymeaCore::instance()->executeAction(action);
|
||||
ThingActionInfo *info = NymeaCore::instance()->thingManager()->executeAction(action);
|
||||
connect(info, &ThingActionInfo::finished, jsonReply, [info, jsonReply, locale](){
|
||||
QVariantMap data;
|
||||
data.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device"));
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
|||
registerEnum<Types::Unit>();
|
||||
registerEnum<Types::InputType>();
|
||||
registerEnum<Types::IOType>();
|
||||
registerEnum<Types::StateValueFilter>();
|
||||
registerEnum<RuleEngine::RemovePolicy>();
|
||||
registerEnum<BrowserItem::BrowserIcon>();
|
||||
registerEnum<MediaBrowserItem::MediaBrowserIcon>();
|
||||
|
|
@ -900,7 +901,7 @@ JsonReply *DeviceHandler::ExecuteAction(const QVariantMap ¶ms, const JsonCon
|
|||
|
||||
JsonReply *jsonReply = createAsyncReply("ExecuteAction");
|
||||
|
||||
ThingActionInfo *info = NymeaCore::instance()->executeAction(action);
|
||||
ThingActionInfo *info = NymeaCore::instance()->thingManager()->executeAction(action);
|
||||
connect(info, &ThingActionInfo::finished, jsonReply, [info, jsonReply, locale](){
|
||||
QVariantMap data;
|
||||
data.insert("deviceError", enumValueName(info->status()).replace("Thing", "Device"));
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ IntegrationsHandler::IntegrationsHandler(ThingManager *thingManager, QObject *pa
|
|||
registerEnum<Types::Unit>();
|
||||
registerEnum<Types::InputType>();
|
||||
registerEnum<Types::IOType>();
|
||||
registerEnum<Types::StateValueFilter>();
|
||||
registerEnum<RuleEngine::RemovePolicy>();
|
||||
registerEnum<BrowserItem::BrowserIcon>();
|
||||
registerEnum<MediaBrowserItem::MediaBrowserIcon>();
|
||||
|
|
@ -958,7 +959,7 @@ JsonReply *IntegrationsHandler::ExecuteAction(const QVariantMap ¶ms, const J
|
|||
|
||||
JsonReply *jsonReply = createAsyncReply("ExecuteAction");
|
||||
|
||||
ThingActionInfo *info = NymeaCore::instance()->executeAction(action);
|
||||
ThingActionInfo *info = NymeaCore::instance()->thingManager()->executeAction(action);
|
||||
connect(info, &ThingActionInfo::finished, jsonReply, [info, jsonReply, locale](){
|
||||
QVariantMap data;
|
||||
data.insert("thingError", enumValueName(info->status()));
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "logging.h"
|
||||
#include "logvaluetool.h"
|
||||
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QSqlDatabase>
|
||||
#include <QSqlDriver>
|
||||
|
|
@ -104,6 +106,13 @@ LogEngine::~LogEngine()
|
|||
m_db.close();
|
||||
}
|
||||
|
||||
void LogEngine::setThingManager(ThingManager *thingManager)
|
||||
{
|
||||
m_thingManager = thingManager;
|
||||
connect(thingManager, &ThingManager::eventTriggered, this, &LogEngine::logEvent);
|
||||
connect(thingManager, &ThingManager::actionExecuted, this, &LogEngine::logAction);
|
||||
}
|
||||
|
||||
LogEntriesFetchJob *LogEngine::fetchLogEntries(const LogFilter &filter)
|
||||
{
|
||||
QList<LogEntry> results;
|
||||
|
|
@ -222,6 +231,10 @@ void LogEngine::logSystemEvent(const QDateTime &dateTime, bool active, Logging::
|
|||
|
||||
void LogEngine::logEvent(const Event &event)
|
||||
{
|
||||
if (!event.logged()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantList valueList;
|
||||
Logging::LoggingSource sourceType;
|
||||
if (event.isStateChangeEvent()) {
|
||||
|
|
@ -249,9 +262,10 @@ void LogEngine::logEvent(const Event &event)
|
|||
appendLogEntry(entry);
|
||||
}
|
||||
|
||||
void LogEngine::logAction(const Action &action, Logging::LoggingLevel level, int errorCode)
|
||||
void LogEngine::logAction(const Action &action, Thing::ThingError status)
|
||||
{
|
||||
LogEntry entry(level, Logging::LoggingSourceActions, errorCode);
|
||||
Logging::LoggingLevel level = status == Thing::ThingErrorNoError ? Logging::LoggingLevelInfo : Logging::LoggingLevelAlert;
|
||||
LogEntry entry(QDateTime::currentDateTime(), level, Logging::LoggingSourceActions, status);
|
||||
entry.setTypeId(action.actionTypeId());
|
||||
entry.setThingId(action.thingId());
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "types/browseritemaction.h"
|
||||
#include "types/browseraction.h"
|
||||
#include "ruleengine/rule.h"
|
||||
#include "integrations/thingmanager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSqlDatabase>
|
||||
|
|
@ -60,6 +61,8 @@ public:
|
|||
LogEngine(const QString &driver, const QString &dbName, const QString &hostname = QString("127.0.0.1"), const QString &username = QString(), const QString &password = QString(), int maxDBSize = 50000, QObject *parent = nullptr);
|
||||
~LogEngine();
|
||||
|
||||
void setThingManager(ThingManager *thingManager);
|
||||
|
||||
LogEntriesFetchJob *fetchLogEntries(const LogFilter &filter = LogFilter());
|
||||
ThingsFetchJob *fetchThings();
|
||||
|
||||
|
|
@ -68,9 +71,11 @@ public:
|
|||
void setMaxLogEntries(int maxLogEntries, int trimSize);
|
||||
void clearDatabase();
|
||||
|
||||
void removeThingLogs(const ThingId &thingId);
|
||||
void removeRuleLogs(const RuleId &ruleId);
|
||||
|
||||
public slots:
|
||||
void logSystemEvent(const QDateTime &dateTime, bool active, Logging::LoggingLevel level = Logging::LoggingLevelInfo);
|
||||
void logEvent(const Event &event);
|
||||
void logAction(const Action &action, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0);
|
||||
void logBrowserAction(const BrowserAction &browserAction, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0);
|
||||
void logBrowserItemAction(const BrowserItemAction &browserItemAction, Logging::LoggingLevel level = Logging::LoggingLevelInfo, int errorCode = 0);
|
||||
void logRuleTriggered(const Rule &rule);
|
||||
|
|
@ -78,8 +83,10 @@ public:
|
|||
void logRuleEnabledChanged(const Rule &rule, const bool &enabled);
|
||||
void logRuleActionsExecuted(const Rule &rule);
|
||||
void logRuleExitActionsExecuted(const Rule &rule);
|
||||
void removeThingLogs(const ThingId &thingId);
|
||||
void removeRuleLogs(const RuleId &ruleId);
|
||||
|
||||
private slots:
|
||||
void logEvent(const Event &event);
|
||||
void logAction(const Action &action, Thing::ThingError status);
|
||||
|
||||
signals:
|
||||
void logEntryAdded(const LogEntry &logEntry);
|
||||
|
|
@ -114,6 +121,8 @@ private:
|
|||
bool m_initialized = false;
|
||||
bool m_dbMalformed = false;
|
||||
|
||||
ThingManager *m_thingManager = nullptr;
|
||||
|
||||
// When maxQueueLength is exceeded, jobs will be flagged and discarded if this source logs more events
|
||||
int m_maxQueueLength;
|
||||
QHash<QString, QList<DatabaseJob*>> m_flaggedJobs;
|
||||
|
|
|
|||
|
|
@ -99,9 +99,6 @@ void NymeaCore::init(const QStringList &additionalInterfaces) {
|
|||
}
|
||||
m_timeManager = new TimeManager(this);
|
||||
|
||||
qCDebug(dcCore) << "Creating Log Engine";
|
||||
m_logger = new LogEngine(m_configuration->logDBDriver(), m_configuration->logDBName(), m_configuration->logDBHost(), m_configuration->logDBUser(), m_configuration->logDBPassword(), m_configuration->logDBMaxEntries(), this);
|
||||
|
||||
qCDebug(dcCore()) << "Creating User Manager";
|
||||
m_userManager = new UserManager(NymeaSettings::settingsPath() + "/user-db.sqlite", this);
|
||||
|
||||
|
|
@ -120,6 +117,10 @@ void NymeaCore::init(const QStringList &additionalInterfaces) {
|
|||
qCDebug(dcCore) << "Creating Rule Engine";
|
||||
m_ruleEngine = new RuleEngine(this);
|
||||
|
||||
qCDebug(dcCore) << "Creating Log Engine";
|
||||
m_logger = new LogEngine(m_configuration->logDBDriver(), m_configuration->logDBName(), m_configuration->logDBHost(), m_configuration->logDBUser(), m_configuration->logDBPassword(), m_configuration->logDBMaxEntries(), this);
|
||||
m_logger->setThingManager(m_thingManager);
|
||||
|
||||
qCDebug(dcCore()) << "Creating Script Engine";
|
||||
m_scriptEngine = new ScriptEngine(m_thingManager, this);
|
||||
m_serverManager->jsonServer()->registerHandler(new ScriptsHandler(m_scriptEngine, m_scriptEngine));
|
||||
|
|
@ -380,20 +381,6 @@ Thing::ThingError NymeaCore::removeConfiguredThing(const ThingId &thingId, const
|
|||
return removeError;
|
||||
}
|
||||
|
||||
ThingActionInfo* NymeaCore::executeAction(const Action &action)
|
||||
{
|
||||
ThingActionInfo *info = m_thingManager->executeAction(action);
|
||||
connect(info, &ThingActionInfo::finished, this, [this, info](){
|
||||
if (info->status() == Thing::ThingErrorNoError) {
|
||||
m_logger->logAction(info->action());
|
||||
} else {
|
||||
m_logger->logAction(info->action(), Logging::LoggingLevelAlert, info->status());
|
||||
}
|
||||
});
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
BrowserActionInfo* NymeaCore::executeBrowserItem(const BrowserAction &browserAction)
|
||||
{
|
||||
BrowserActionInfo *info = m_thingManager->executeBrowserItem(browserAction);
|
||||
|
|
@ -512,7 +499,7 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
|||
|
||||
foreach (const Action &action, actions) {
|
||||
qCDebug(dcRuleEngine) << "Executing action" << action.actionTypeId() << action.params();
|
||||
ThingActionInfo *info = executeAction(action);
|
||||
ThingActionInfo *info = m_thingManager->executeAction(action);
|
||||
connect(info, &ThingActionInfo::finished, this, [info](){
|
||||
if (info->status() != Thing::ThingErrorNoError) {
|
||||
qCWarning(dcRuleEngine) << "Error executing action:" << info->status() << info->displayMessage();
|
||||
|
|
@ -660,17 +647,6 @@ ZigbeeManager *NymeaCore::zigbeeManager() const
|
|||
|
||||
void NymeaCore::gotEvent(const Event &event)
|
||||
{
|
||||
Thing *thing = m_thingManager->findConfiguredThing(event.thingId());
|
||||
ThingClass thingClass = thing ? thing->thingClass() : ThingClass();
|
||||
EventType eventType = thingClass.eventTypes().findById(event.eventTypeId());
|
||||
foreach (const QString &interfaceName, thingClass.interfaces()) {
|
||||
Interface iface = m_thingManager->supportedInterfaces().findByName(interfaceName);
|
||||
if (iface.eventTypes().findByName(eventType.name()).logged()) {
|
||||
m_logger->logEvent(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit eventTriggered(event);
|
||||
|
||||
QList<RuleAction> actions;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ public:
|
|||
QPair<Thing::ThingError, QList<RuleId> >removeConfiguredThing(const ThingId &thingId, const QHash<RuleId, RuleEngine::RemovePolicy> &removePolicyList);
|
||||
Thing::ThingError removeConfiguredThing(const ThingId &thingId, const RuleEngine::RemovePolicy &removePolicy);
|
||||
|
||||
ThingActionInfo *executeAction(const Action &action);
|
||||
BrowserActionInfo* executeBrowserItem(const BrowserAction &browserAction);
|
||||
BrowserItemActionInfo* executeBrowserItemAction(const BrowserItemAction &browserItemAction);
|
||||
|
||||
|
|
|
|||
|
|
@ -469,6 +469,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
break;
|
||||
}
|
||||
stateType.setIOType(ioType);
|
||||
stateType.setSuggestLogging(st.value("suggestLogging").toBool());
|
||||
}
|
||||
stateTypes.append(stateType);
|
||||
|
||||
|
|
@ -485,6 +486,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
paramType.setUnit(stateType.unit());
|
||||
eventType.setParamTypes(QList<ParamType>() << paramType);
|
||||
eventType.setIndex(stateType.index());
|
||||
eventType.setSuggestLogging(st.value("suggestLogging").toBool());
|
||||
eventTypes.append(eventType);
|
||||
|
||||
// ActionTypes for writeable StateTypes
|
||||
|
|
@ -497,7 +499,6 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
actionTypes.append(actionType);
|
||||
}
|
||||
}
|
||||
thingClass.setStateTypes(stateTypes);
|
||||
|
||||
// ActionTypes
|
||||
index = 0;
|
||||
|
|
@ -544,7 +545,6 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
|
||||
actionTypes.append(actionType);
|
||||
}
|
||||
thingClass.setActionTypes(actionTypes);
|
||||
|
||||
// EventTypes
|
||||
index = 0;
|
||||
|
|
@ -580,6 +580,7 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
EventType eventType(eventTypeId);
|
||||
eventType.setName(eventTypeName);
|
||||
eventType.setDisplayName(et.value("displayName").toString());
|
||||
eventType.setSuggestLogging(et.value("suggestLogging").toBool());
|
||||
eventType.setIndex(index++);
|
||||
|
||||
QPair<bool, QList<ParamType> > paramVerification = parseParamTypes(et.value("paramTypes").toArray());
|
||||
|
|
@ -590,7 +591,6 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
}
|
||||
eventTypes.append(eventType);
|
||||
}
|
||||
thingClass.setEventTypes(eventTypes);
|
||||
|
||||
// BrowserItemActionTypes
|
||||
index = 0;
|
||||
|
|
@ -637,7 +637,6 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
|
||||
browserItemActionTypes.append(actionType);
|
||||
}
|
||||
thingClass.setBrowserItemActionTypes(browserItemActionTypes);
|
||||
|
||||
// Read interfaces
|
||||
QStringList interfaces;
|
||||
|
|
@ -646,22 +645,18 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
if (!iface.isValid()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" uses non-existing interface \"" + value.toString() + "\"");
|
||||
hasError = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
StateTypes stateTypes(thingClass.stateTypes());
|
||||
ActionTypes actionTypes(thingClass.actionTypes());
|
||||
EventTypes eventTypes(thingClass.eventTypes());
|
||||
|
||||
foreach (const InterfaceStateType &ifaceStateType, iface.stateTypes()) {
|
||||
StateType stateType = stateTypes.findByName(ifaceStateType.name());
|
||||
if (stateType.id().isNull()) {
|
||||
if (!stateTypes.contains(ifaceStateType.name())) {
|
||||
if (!ifaceStateType.optional()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement state \"" + ifaceStateType.name() + "\"");
|
||||
hasError = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
StateType &stateType = stateTypes[ifaceStateType.name()];
|
||||
if (ifaceStateType.type() != stateType.type()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has not matching type: \"" + QVariant::typeToName(stateType.type()) + "\" != \"" + QVariant::typeToName(ifaceStateType.type()) + "\"");
|
||||
hasError = true;
|
||||
|
|
@ -697,18 +692,22 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but state \"" + stateType.name() + "\" has not matching unit: \"" + unitEnum.valueToKey(ifaceStateType.unit()) + "\" != \"" + unitEnum.valueToKey(stateType.unit()));
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
// Override logged property as the interface has higher priority than the plugin dev
|
||||
if (ifaceStateType.loggingOverride()) {
|
||||
stateType.setSuggestLogging(ifaceStateType.suggestLogging());
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const InterfaceActionType &ifaceActionType, iface.actionTypes()) {
|
||||
ActionType actionType = actionTypes.findByName(ifaceActionType.name());
|
||||
if (actionType.id().isNull()) {
|
||||
if (!actionTypes.contains(ifaceActionType.name())) {
|
||||
if (!ifaceActionType.optional()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement action \"" + ifaceActionType.name() + "\"");
|
||||
hasError = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ActionType &actionType = actionTypes[ifaceActionType.name()];
|
||||
// Verify the params as required by the interface are available
|
||||
foreach (const ParamType &ifaceActionParamType, ifaceActionType.paramTypes()) {
|
||||
ParamType paramType = actionType.paramTypes().findByName(ifaceActionParamType.name());
|
||||
|
|
@ -779,15 +778,14 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
}
|
||||
|
||||
foreach (const InterfaceEventType &ifaceEventType, iface.eventTypes()) {
|
||||
EventType eventType = eventTypes.findByName(ifaceEventType.name());
|
||||
if (!eventType.isValid()) {
|
||||
if (!eventTypes.contains(ifaceEventType.name())) {
|
||||
if (!ifaceEventType.optional()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" claims to implement interface \"" + value.toString() + "\" but doesn't implement event \"" + ifaceEventType.name() + "\"");
|
||||
hasError = true;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
EventType &eventType = eventTypes[ifaceEventType.name()];
|
||||
|
||||
// Verify all the params as required by the interface are available
|
||||
foreach (const ParamType &ifaceEventParamType, ifaceEventType.paramTypes()) {
|
||||
|
|
@ -842,6 +840,11 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
}
|
||||
}
|
||||
|
||||
// Override logging
|
||||
if (ifaceEventType.loggingOverride()) {
|
||||
eventType.setSuggestLogging(ifaceEventType.suggestLogging());
|
||||
}
|
||||
|
||||
// Note: No need to check for default values (as with actions) for additional params as
|
||||
// an emitted event always needs to have params filled with values. The client might use them or not...
|
||||
}
|
||||
|
|
@ -851,6 +854,11 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
|||
interfaces.removeDuplicates();
|
||||
thingClass.setInterfaces(interfaces);
|
||||
|
||||
thingClass.setStateTypes(stateTypes);
|
||||
thingClass.setActionTypes(actionTypes);
|
||||
thingClass.setEventTypes(eventTypes);
|
||||
thingClass.setBrowserItemActionTypes(browserItemActionTypes);
|
||||
|
||||
m_thingClasses.append(thingClass);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
#include "statevaluefilter.h"
|
||||
|
||||
StateValueFilter::StateValueFilter()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef STATEVALUEFILTER_H
|
||||
#define STATEVALUEFILTER_H
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
class StateValueFilter
|
||||
{
|
||||
public:
|
||||
StateValueFilter();
|
||||
virtual ~StateValueFilter();
|
||||
|
||||
virtual void addValue(const QVariant &value) = 0;
|
||||
|
||||
virtual QVariant filteredValue() const = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // STATEVALUEFILTER_H
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#include "statevaluefilteradaptive.h"
|
||||
|
||||
StateValueFilterAdaptive::StateValueFilterAdaptive()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void StateValueFilterAdaptive::addValue(const QVariant &value)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef STATEVALUEFILTERADAPTIVE_H
|
||||
#define STATEVALUEFILTERADAPTIVE_H
|
||||
|
||||
#include "statevaluefilter.h"
|
||||
|
||||
class StateValueFilterAdaptive : public StateValueFilter
|
||||
{
|
||||
public:
|
||||
StateValueFilterAdaptive();
|
||||
|
||||
void addValue(const QVariant &value) override;
|
||||
QVariant filteredValue() const override;
|
||||
};
|
||||
|
||||
#endif // STATEVALUEFILTERADAPTIVE_H
|
||||
|
|
@ -133,6 +133,7 @@
|
|||
#include "thing.h"
|
||||
#include "types/event.h"
|
||||
#include "loggingcategories.h"
|
||||
#include "statevaluefilters/statevaluefilteradaptive.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
|
@ -334,9 +335,6 @@ void Thing::setStateValue(const StateTypeId &stateTypeId, const QVariant &value)
|
|||
}
|
||||
for (int i = 0; i < m_states.count(); ++i) {
|
||||
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
||||
if (m_states.at(i).value() == value)
|
||||
return;
|
||||
|
||||
QVariant newValue = value;
|
||||
if (!newValue.convert(stateType.type())) {
|
||||
qCWarning(dcThing()).nospace() << m_name << ": Invalid value " << value << " for state " << stateType.name() << ". Type mismatch. Expected type: " << QVariant::typeToName(stateType.type()) << " (Discarding change)";
|
||||
|
|
@ -355,8 +353,13 @@ void Thing::setStateValue(const StateTypeId &stateTypeId, const QVariant &value)
|
|||
return;
|
||||
}
|
||||
|
||||
QVariant oldValue = m_states.at(i).value();
|
||||
StateValueFilter *filter = m_stateValueFilters.value(stateTypeId);
|
||||
if (filter) {
|
||||
filter->addValue(newValue);
|
||||
newValue = filter->filteredValue();
|
||||
}
|
||||
|
||||
QVariant oldValue = m_states.at(i).value();
|
||||
if (oldValue == newValue) {
|
||||
qCDebug(dcThing()).nospace() << m_name << ": Discarding state change for " << stateType.name() << " as the value did not actually change. Old value:" << oldValue << "New value:" << newValue;
|
||||
return;
|
||||
|
|
@ -383,22 +386,9 @@ State Thing::state(const StateTypeId &stateTypeId) const
|
|||
return State(StateTypeId(), ThingId());
|
||||
}
|
||||
|
||||
void Thing::setStateLogged(const StateTypeId &stateTypeId, bool logged)
|
||||
QList<EventTypeId> Thing::loggedEventTypeIds() const
|
||||
{
|
||||
for (int i = 0; i < m_states.count(); i++) {
|
||||
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
||||
m_states[i].setLogged(logged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Thing::setStateFilter(const StateTypeId &stateTypeId, Types::StateValueFilter filter)
|
||||
{
|
||||
for (int i = 0; i < m_states.count(); i++) {
|
||||
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
||||
m_states[i].setFilter(filter);
|
||||
}
|
||||
}
|
||||
return m_loggedEventTypeIds;
|
||||
}
|
||||
|
||||
/*! Returns the \l{ThingId} of the parent of this thing. If the parentId
|
||||
|
|
@ -460,6 +450,27 @@ void Thing::setSetupStatus(Thing::ThingSetupStatus status, Thing::ThingError set
|
|||
emit setupStatusChanged();
|
||||
}
|
||||
|
||||
void Thing::setLoggedEventTypeIds(const QList<EventTypeId> loggedEventTypeIds)
|
||||
{
|
||||
m_loggedEventTypeIds = loggedEventTypeIds;
|
||||
}
|
||||
|
||||
void Thing::setStateValueFilter(const StateTypeId &stateTypeId, Types::StateValueFilter filter)
|
||||
{
|
||||
for (int i = 0; i < m_states.count(); i++) {
|
||||
if (m_states.at(i).stateTypeId() == stateTypeId) {
|
||||
m_states[i].setFilter(filter);
|
||||
StateValueFilter *stateValueFilter = m_stateValueFilters.take(stateTypeId);
|
||||
if (stateValueFilter) {
|
||||
delete stateValueFilter;
|
||||
}
|
||||
if (filter == Types::StateValueFilterAdaptive) {
|
||||
m_stateValueFilters.insert(stateTypeId, new StateValueFilterAdaptive());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Things::Things(const QList<Thing*> &other)
|
||||
{
|
||||
foreach (Thing* thing, other) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include <QVariant>
|
||||
|
||||
class IntegrationPlugin;
|
||||
class StateValueFilter;
|
||||
|
||||
class LIBNYMEA_EXPORT Thing: public QObject
|
||||
{
|
||||
|
|
@ -60,6 +61,7 @@ class LIBNYMEA_EXPORT Thing: public QObject
|
|||
Q_PROPERTY(QString setupDisplayMessage READ setupDisplayMessage NOTIFY setupStatusChanged USER true)
|
||||
Q_PROPERTY(ThingError setupError READ setupError NOTIFY setupStatusChanged)
|
||||
Q_PROPERTY(QUuid parentId READ parentId USER true)
|
||||
Q_PROPERTY(QList<EventTypeId> loggedEventTypeIds READ loggedEventTypeIds USER true)
|
||||
|
||||
public:
|
||||
enum ThingError {
|
||||
|
|
@ -133,8 +135,7 @@ public:
|
|||
|
||||
Q_INVOKABLE State state(const StateTypeId &stateTypeId) const;
|
||||
|
||||
void setStateLogged(const StateTypeId &stateTypeId, bool logged);
|
||||
void setStateFilter(const StateTypeId &stateTypeId, Types::StateValueFilter filter);
|
||||
QList<EventTypeId> loggedEventTypeIds() const;
|
||||
|
||||
ThingId parentId() const;
|
||||
void setParentId(const ThingId &parentId);
|
||||
|
|
@ -164,6 +165,8 @@ private:
|
|||
Thing(const PluginId &pluginId, const ThingClass &thingClass, QObject *parent = nullptr);
|
||||
|
||||
void setSetupStatus(ThingSetupStatus status, ThingError setupError, const QString &displayMessage = QString());
|
||||
void setLoggedEventTypeIds(const QList<EventTypeId> loggedEventTypeIds);
|
||||
void setStateValueFilter(const StateTypeId &stateTypeId, Types::StateValueFilter filter);
|
||||
|
||||
private:
|
||||
ThingClass m_thingClass;
|
||||
|
|
@ -179,6 +182,9 @@ private:
|
|||
ThingSetupStatus m_setupStatus = ThingSetupStatusNone;
|
||||
ThingError m_setupError = ThingErrorNoError;
|
||||
QString m_setupDisplayMessage;
|
||||
|
||||
QList<EventTypeId> m_loggedEventTypeIds;
|
||||
QHash<StateTypeId, StateValueFilter*> m_stateValueFilters;
|
||||
};
|
||||
|
||||
QDebug operator<<(QDebug dbg, Thing *device);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ signals:
|
|||
void thingSettingChanged(const ThingId &thingId, const ParamTypeId &settingParamTypeId, const QVariant &value);
|
||||
void ioConnectionAdded(const IOConnection &ioConnection);
|
||||
void ioConnectionRemoved(const IOConnectionId &ioConnectionId);
|
||||
void actionExecuted(const Action &action, Thing::ThingError status);
|
||||
};
|
||||
|
||||
#endif // THINGMANAGER_H
|
||||
|
|
|
|||
|
|
@ -200,7 +200,10 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
stateType.setMinValue(stateVariant.toMap().value("minValue"));
|
||||
stateType.setMaxValue(stateVariant.toMap().value("maxValue"));
|
||||
stateType.setOptional(stateVariant.toMap().value("optional", false).toBool());
|
||||
stateType.setLogged(stateVariant.toMap().value("logged", false).toBool());
|
||||
if (stateVariant.toMap().contains("logged")) {
|
||||
stateType.setLoggingOverride(true);
|
||||
stateType.setSuggestLogging(stateVariant.toMap().value("logged", false).toBool());
|
||||
}
|
||||
if (stateVariant.toMap().contains("unit")) {
|
||||
QMetaEnum unitEnum = QMetaEnum::fromType<Types::Unit>();
|
||||
int enumValue = unitEnum.keyToValue("Unit" + stateVariant.toMap().value("unit").toByteArray());
|
||||
|
|
@ -215,7 +218,8 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
InterfaceEventType stateChangeEventType;
|
||||
stateChangeEventType.setName(stateType.name());
|
||||
stateChangeEventType.setOptional(stateType.optional());
|
||||
stateChangeEventType.setLogged(stateType.logged());
|
||||
stateChangeEventType.setSuggestLogging(stateType.suggestLogging());
|
||||
stateChangeEventType.setLoggingOverride(stateType.loggingOverride());
|
||||
ParamType stateChangeEventParamType;
|
||||
stateChangeEventParamType.setName(stateType.name());
|
||||
stateChangeEventParamType.setType(stateType.type());
|
||||
|
|
@ -238,6 +242,10 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
InterfaceActionType actionType;
|
||||
actionType.setName(actionVariant.toMap().value("name").toString());
|
||||
actionType.setOptional(actionVariant.toMap().value("optional").toBool());
|
||||
// if (actionVariant.toMap().contains("logged")) {
|
||||
// actionType.setLoggingOverride(true);
|
||||
// actionType.setSuggestLogging(actionVariant.toMap().value("logged").toBool());
|
||||
// }
|
||||
ParamTypes paramTypes;
|
||||
foreach (const QVariant &actionParamVariant, actionVariant.toMap().value("params").toList()) {
|
||||
ParamType paramType;
|
||||
|
|
@ -256,7 +264,10 @@ Interface ThingUtils::loadInterface(const QString &name)
|
|||
InterfaceEventType eventType;
|
||||
eventType.setName(eventVariant.toMap().value("name").toString());
|
||||
eventType.setOptional(eventVariant.toMap().value("optional").toBool());
|
||||
eventType.setLogged(eventVariant.toMap().value("logged").toBool());
|
||||
if (eventVariant.toMap().contains("logged")) {
|
||||
eventType.setLoggingOverride(true);
|
||||
eventType.setSuggestLogging(eventVariant.toMap().value("logged").toBool());
|
||||
}
|
||||
ParamTypes paramTypes;
|
||||
foreach (const QVariant &eventParamVariant, eventVariant.toMap().value("params").toList()) {
|
||||
ParamType paramType;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "jsonhandler.h"
|
||||
|
||||
#include "typeutils.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
|
@ -207,6 +207,9 @@ void JsonHandler::registerObject(const QMetaObject &metaObject)
|
|||
typeName = QString("$ref:BasicType");
|
||||
} else if (QString(metaProperty.typeName()).startsWith("QList")) {
|
||||
QString elementType = QString(metaProperty.typeName()).remove("QList<").remove(">");
|
||||
if (elementType == "EventTypeId" || elementType == "StateTypeId" || elementType == "ActionTypeId") {
|
||||
elementType = "QUuid";
|
||||
}
|
||||
QVariant::Type variantType = QVariant::nameToType(elementType.toUtf8());
|
||||
typeName = QVariantList() << enumValueName(variantTypeToBasicType(variantType));
|
||||
} else {
|
||||
|
|
@ -344,6 +347,18 @@ QVariant JsonHandler::pack(const QMetaObject &metaObject, const void *value) con
|
|||
foreach (const QUuid &entry, propertyValue.value<QList<QUuid>>()) {
|
||||
list << entry;
|
||||
}
|
||||
} else if (propertyTypeName == "QList<EventTypeId>") {
|
||||
foreach (const EventTypeId &entry, propertyValue.value<QList<EventTypeId>>()) {
|
||||
list << entry;
|
||||
}
|
||||
} else if (propertyTypeName == "QList<StateTypeId>") {
|
||||
foreach (const EventTypeId &entry, propertyValue.value<QList<EventTypeId>>()) {
|
||||
list << entry;
|
||||
}
|
||||
} else if (propertyTypeName == "QList<ActionTypeId>") {
|
||||
foreach (const EventTypeId &entry, propertyValue.value<QList<EventTypeId>>()) {
|
||||
list << entry;
|
||||
}
|
||||
} else {
|
||||
Q_ASSERT_X(false, this->metaObject()->className(), QString("Unhandled list type: %1").arg(propertyTypeName).toUtf8());
|
||||
qCWarning(dcJsonRpc()) << "Cannot pack property of unhandled list type" << propertyTypeName;
|
||||
|
|
@ -455,7 +470,10 @@ QVariant JsonHandler::unpack(const QMetaObject &metaObject, const QVariant &valu
|
|||
intList.append(val.toInt());
|
||||
}
|
||||
metaProperty.writeOnGadget(ptr, QVariant::fromValue(intList));
|
||||
} else if (metaProperty.typeName() == QStringLiteral("QList<QUuid>")) {
|
||||
} else if (metaProperty.typeName() == QStringLiteral("QList<QUuid>")
|
||||
|| metaProperty.typeName() == QStringLiteral("QList<EventTypeId>")
|
||||
|| metaProperty.typeName() == QStringLiteral("QList<StateTypeId>")
|
||||
|| metaProperty.typeName() == QStringLiteral("QList<ActionTypeId>")) {
|
||||
QList<QUuid> uuidList;
|
||||
foreach (const QVariant &val, variant.toList()) {
|
||||
uuidList.append(val.toUuid());
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ SOURCES += \
|
|||
integrations/thingsetupinfo.cpp \
|
||||
integrations/thingutils.cpp \
|
||||
integrations/servicedata.cpp \
|
||||
integrations/statevaluefilters/statevaluefilter.cpp \
|
||||
integrations/statevaluefilters/statevaluefilteradaptive.cpp \
|
||||
jsonrpc/jsoncontext.cpp \
|
||||
jsonrpc/jsonhandler.cpp \
|
||||
jsonrpc/jsonreply.cpp \
|
||||
|
|
|
|||
|
|
@ -130,6 +130,26 @@ ActionTypes::ActionTypes(const QList<ActionType> &other)
|
|||
}
|
||||
}
|
||||
|
||||
bool ActionTypes::contains(const ActionTypeId &id) const
|
||||
{
|
||||
foreach (const ActionType &actionType, *this) {
|
||||
if (actionType.id() == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ActionTypes::contains(const QString &name) const
|
||||
{
|
||||
foreach (const ActionType &actionType, *this) {
|
||||
if (actionType.name() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant ActionTypes::get(int index) const
|
||||
{
|
||||
return QVariant::fromValue(at(index));
|
||||
|
|
@ -160,8 +180,21 @@ ActionType ActionTypes::findById(const ActionTypeId &id)
|
|||
return ActionType(ActionTypeId());
|
||||
}
|
||||
|
||||
ActionType &ActionTypes::operator[](const QString &name)
|
||||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < count(); i++) {
|
||||
if (at(i).name() == name) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QList::operator[](index);
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const ActionType &actionType)
|
||||
{
|
||||
dbg.nospace().noquote() << "ActionType: " << actionType.name() << actionType.displayName() << actionType.id();
|
||||
return dbg;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,10 +84,13 @@ class ActionTypes: public QList<ActionType>
|
|||
public:
|
||||
ActionTypes() = default;
|
||||
ActionTypes(const QList<ActionType> &other);
|
||||
bool contains(const ActionTypeId &id) const;
|
||||
bool contains(const QString &name) const;
|
||||
Q_INVOKABLE QVariant get(int index) const;
|
||||
Q_INVOKABLE void put(const QVariant &variant);
|
||||
ActionType findByName(const QString &name);
|
||||
ActionType findById(const ActionTypeId &id);
|
||||
ActionType &operator[](const QString &name);
|
||||
};
|
||||
Q_DECLARE_METATYPE(ActionTypes)
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,16 @@ bool Event::isStateChangeEvent() const
|
|||
return m_isStateChangeEvent;
|
||||
}
|
||||
|
||||
bool Event::logged() const
|
||||
{
|
||||
return m_logged;
|
||||
}
|
||||
|
||||
void Event::setLogged(bool logged)
|
||||
{
|
||||
m_logged = logged;
|
||||
}
|
||||
|
||||
/*! Compare this Event to the Event given by \a other.
|
||||
* Events are equal (returns true) if eventTypeId, deviceId and params match. */
|
||||
bool Event::operator ==(const Event &other) const
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ class LIBNYMEA_EXPORT Event
|
|||
Q_PROPERTY(QUuid thingId READ thingId)
|
||||
Q_PROPERTY(QUuid deviceId READ thingId REVISION 1)
|
||||
Q_PROPERTY(ParamList params READ params)
|
||||
Q_PROPERTY(bool logged READ logged)
|
||||
public:
|
||||
Event();
|
||||
Event(const EventTypeId &eventTypeId, const ThingId &thingId, const ParamList ¶ms = ParamList(), bool isStateChangeEvent = false);
|
||||
|
|
@ -65,12 +66,16 @@ public:
|
|||
|
||||
bool isStateChangeEvent() const;
|
||||
|
||||
bool logged() const;
|
||||
void setLogged(bool logged);
|
||||
|
||||
private:
|
||||
EventTypeId m_eventTypeId;
|
||||
ThingId m_thingId;
|
||||
ParamList m_params;
|
||||
|
||||
bool m_isStateChangeEvent;
|
||||
bool m_logged = false;
|
||||
};
|
||||
Q_DECLARE_METATYPE(Event)
|
||||
QDebug operator<<(QDebug dbg, const Event &event);
|
||||
|
|
|
|||
|
|
@ -110,6 +110,16 @@ void EventType::setParamTypes(const ParamTypes ¶mTypes)
|
|||
m_paramTypes = paramTypes;
|
||||
}
|
||||
|
||||
bool EventType::suggestLogging() const
|
||||
{
|
||||
return m_logged;
|
||||
}
|
||||
|
||||
void EventType::setSuggestLogging(bool logged)
|
||||
{
|
||||
m_logged = logged;
|
||||
}
|
||||
|
||||
/*! Returns true if this EventType has a valid id and name */
|
||||
bool EventType::isValid() const
|
||||
{
|
||||
|
|
@ -130,11 +140,31 @@ QStringList EventType::mandatoryTypeProperties()
|
|||
|
||||
EventTypes::EventTypes(const QList<EventType> &other)
|
||||
{
|
||||
foreach (const EventType &at, other) {
|
||||
append(at);
|
||||
foreach (const EventType &et, other) {
|
||||
append(et);
|
||||
}
|
||||
}
|
||||
|
||||
bool EventTypes::contains(const EventTypeId &id) const
|
||||
{
|
||||
foreach (const EventType &eventType, *this) {
|
||||
if (eventType.id() == id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EventTypes::contains(const QString &name) const
|
||||
{
|
||||
foreach (const EventType &eventType, *this) {
|
||||
if (eventType.name() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant EventTypes::get(int index) const
|
||||
{
|
||||
return QVariant::fromValue(at(index));
|
||||
|
|
@ -164,3 +194,15 @@ EventType EventTypes::findById(const EventTypeId &id)
|
|||
}
|
||||
return EventType(EventTypeId());
|
||||
}
|
||||
|
||||
EventType &EventTypes::operator[](const QString &name)
|
||||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < count(); i++) {
|
||||
if (at(i).name() == name) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QList::operator[](index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,9 @@ public:
|
|||
ParamTypes paramTypes() const;
|
||||
void setParamTypes(const ParamTypes ¶mTypes);
|
||||
|
||||
bool suggestLogging() const;
|
||||
void setSuggestLogging(bool logged);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
static QStringList typeProperties();
|
||||
|
|
@ -75,6 +78,7 @@ private:
|
|||
QString m_displayName;
|
||||
int m_index;
|
||||
QList<ParamType> m_paramTypes;
|
||||
bool m_logged = false;
|
||||
};
|
||||
Q_DECLARE_METATYPE(EventType)
|
||||
|
||||
|
|
@ -85,10 +89,13 @@ class EventTypes: public QList<EventType>
|
|||
public:
|
||||
EventTypes() = default;
|
||||
EventTypes(const QList<EventType> &other);
|
||||
bool contains(const EventTypeId &id) const;
|
||||
bool contains(const QString &name) const;
|
||||
Q_INVOKABLE QVariant get(int index) const;
|
||||
Q_INVOKABLE void put(const QVariant &variant);
|
||||
EventType findByName(const QString &name);
|
||||
EventType findById(const EventTypeId &id);
|
||||
EventType &operator[](const QString &name);
|
||||
};
|
||||
Q_DECLARE_METATYPE(EventTypes)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@ void InterfaceEventType::setOptional(bool optional)
|
|||
m_optional = optional;
|
||||
}
|
||||
|
||||
bool InterfaceEventType::logged() const
|
||||
bool InterfaceEventType::loggingOverride() const
|
||||
{
|
||||
return m_logged;
|
||||
return m_loggingOverride;
|
||||
}
|
||||
|
||||
void InterfaceEventType::setLogged(bool logged)
|
||||
void InterfaceEventType::setLoggingOverride(bool loggingOverride)
|
||||
{
|
||||
m_logged = logged;
|
||||
m_loggingOverride = loggingOverride;
|
||||
}
|
||||
|
||||
InterfaceEventTypes::InterfaceEventTypes(const QList<InterfaceEventType> &other):
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ public:
|
|||
bool optional() const;
|
||||
void setOptional(bool optional);
|
||||
|
||||
bool logged() const;
|
||||
void setLogged(bool logged);
|
||||
bool loggingOverride() const;
|
||||
void setLoggingOverride(bool loggingOverride);
|
||||
|
||||
private:
|
||||
bool m_optional = false;
|
||||
bool m_logged = false;
|
||||
bool m_loggingOverride = false;
|
||||
};
|
||||
|
||||
class InterfaceEventTypes: public QList<InterfaceEventType>
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@ void InterfaceStateType::setOptional(bool optional)
|
|||
m_optional = optional;
|
||||
}
|
||||
|
||||
bool InterfaceStateType::logged() const
|
||||
bool InterfaceStateType::loggingOverride() const
|
||||
{
|
||||
return m_logged;
|
||||
return m_loggingOverride;
|
||||
}
|
||||
|
||||
void InterfaceStateType::setLogged(bool logged)
|
||||
void InterfaceStateType::setLoggingOverride(bool loggingOverride)
|
||||
{
|
||||
m_logged = logged;
|
||||
m_loggingOverride = loggingOverride;
|
||||
}
|
||||
|
||||
InterfaceStateTypes::InterfaceStateTypes(const QList<InterfaceStateType> &other):
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ public:
|
|||
bool optional() const;
|
||||
void setOptional(bool optional);
|
||||
|
||||
bool logged() const;
|
||||
void setLogged(bool logged);
|
||||
bool loggingOverride() const;
|
||||
void setLoggingOverride(bool loggingOverride);
|
||||
|
||||
private:
|
||||
bool m_optional = false;
|
||||
bool m_logged = false;
|
||||
bool m_loggingOverride = false;
|
||||
};
|
||||
|
||||
class InterfaceStateTypes: public QList<InterfaceStateType>
|
||||
|
|
|
|||
|
|
@ -90,16 +90,6 @@ void State::setFilter(Types::StateValueFilter filter)
|
|||
m_filter = filter;
|
||||
}
|
||||
|
||||
bool State::logged() const
|
||||
{
|
||||
return m_logged;
|
||||
}
|
||||
|
||||
void State::setLogged(bool logged)
|
||||
{
|
||||
m_logged = logged;
|
||||
}
|
||||
|
||||
/*! Writes the stateTypeId, the deviceId and the value of the given \a state to \a dbg. */
|
||||
QDebug operator<<(QDebug dbg, const State &state)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ class LIBNYMEA_EXPORT State
|
|||
Q_PROPERTY(QUuid stateTypeId READ stateTypeId)
|
||||
Q_PROPERTY(QVariant value READ value)
|
||||
Q_PROPERTY(Types::StateValueFilter filter READ filter)
|
||||
Q_PROPERTY(bool logged READ logged)
|
||||
|
||||
public:
|
||||
State();
|
||||
|
|
@ -58,15 +57,11 @@ public:
|
|||
Types::StateValueFilter filter() const;
|
||||
void setFilter(Types::StateValueFilter filter);
|
||||
|
||||
bool logged() const;
|
||||
void setLogged(bool logged);
|
||||
|
||||
private:
|
||||
StateTypeId m_stateTypeId;
|
||||
ThingId m_thingId;
|
||||
QVariant m_value;
|
||||
Types::StateValueFilter m_filter;
|
||||
bool m_logged = false;
|
||||
Types::StateValueFilter m_filter = Types::StateValueFilterNone;
|
||||
};
|
||||
Q_DECLARE_METATYPE(State)
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,16 @@ void StateType::setCached(bool cached)
|
|||
m_cached = cached;
|
||||
}
|
||||
|
||||
bool StateType::suggestLogging() const
|
||||
{
|
||||
return m_logged;
|
||||
}
|
||||
|
||||
void StateType::setSuggestLogging(bool logged)
|
||||
{
|
||||
m_logged = logged;
|
||||
}
|
||||
|
||||
Types::StateValueFilter StateType::filter() const
|
||||
{
|
||||
return m_filter;
|
||||
|
|
@ -223,7 +233,7 @@ QStringList StateType::typeProperties()
|
|||
{
|
||||
return QStringList() << "id" << "name" << "displayName" << "displayNameEvent" << "type" << "defaultValue"
|
||||
<< "cached" << "unit" << "minValue" << "maxValue" << "possibleValues" << "writable"
|
||||
<< "displayNameAction" << "ioType";
|
||||
<< "displayNameAction" << "ioType" << "logged";
|
||||
}
|
||||
|
||||
/*! Returns a list of mandatory properties a DeviceClass definition must have. */
|
||||
|
|
@ -255,6 +265,16 @@ bool StateTypes::contains(const StateTypeId &stateTypeId)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool StateTypes::contains(const QString &name)
|
||||
{
|
||||
foreach (const StateType &stateType, *this) {
|
||||
if (stateType.name() == name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant StateTypes::get(int index) const
|
||||
{
|
||||
return QVariant::fromValue(at(index));
|
||||
|
|
@ -284,3 +304,15 @@ StateType StateTypes::findById(const StateTypeId &id)
|
|||
}
|
||||
return StateType(StateTypeId());
|
||||
}
|
||||
|
||||
StateType &StateTypes::operator[](const QString &name)
|
||||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < count(); i++) {
|
||||
if (at(i).name() == name) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QList::operator[](index);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ public:
|
|||
bool cached() const;
|
||||
void setCached(bool cached);
|
||||
|
||||
bool logged() const;
|
||||
void setLogged(bool logged);
|
||||
bool suggestLogging() const;
|
||||
void setSuggestLogging(bool logged);
|
||||
|
||||
Types::StateValueFilter filter() const;
|
||||
void setFilter(Types::StateValueFilter filter);
|
||||
|
|
@ -131,10 +131,12 @@ public:
|
|||
StateTypes() = default;
|
||||
StateTypes(const QList<StateType> &other);
|
||||
bool contains(const StateTypeId &stateTypeId);
|
||||
bool contains(const QString &name);
|
||||
Q_INVOKABLE QVariant get(int index) const;
|
||||
Q_INVOKABLE void put(const QVariant &variant);
|
||||
StateType findByName(const QString &name);
|
||||
StateType findById(const StateTypeId &id);
|
||||
StateType &operator[](const QString &name);
|
||||
};
|
||||
Q_DECLARE_METATYPE(StateTypes)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue