Add support for generic IO connections
This commit is contained in:
parent
9af820b696
commit
9f856f3ce9
4
debian/changelog
vendored
4
debian/changelog
vendored
@ -1,3 +1,7 @@
|
||||
nymea (0.21.0) UNRELEASED; urgency=medium
|
||||
|
||||
-- Michael Zanetti <michael.zanetti@guh.io> Thu, 09 Apr 2020 18:19:52 +0200
|
||||
|
||||
nymea (0.20.0) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
|
||||
@ -168,7 +168,7 @@ void CloudNotifications::startMonitoringAutoThings()
|
||||
|
||||
void CloudNotifications::executeAction(ThingActionInfo *info)
|
||||
{
|
||||
qCDebug(dcCloud()) << "executeAction" << info->thing() << info->action().id() << info->action().params();
|
||||
qCDebug(dcCloud()) << "executeAction" << info->thing() << info->action().params();
|
||||
QString userId = info->thing()->paramValue(cloudNotificationsThingClassUserParamId).toString();
|
||||
QString endpointId = info->thing()->paramValue(cloudNotificationsThingClassEndpointParamId).toString();
|
||||
int id = m_awsConnector->sendPushNotification(userId, endpointId, info->action().param(notifyActionParamTitleId).value().toString(), info->action().param(notifyActionParamBodyId).value().toString());
|
||||
|
||||
@ -760,6 +760,13 @@ Thing::ThingError ThingManagerImplementation::removeConfiguredThing(const ThingI
|
||||
NymeaSettings stateCache(NymeaSettings::SettingsRoleThingStates);
|
||||
stateCache.remove(thingId.toString());
|
||||
|
||||
foreach (const IOConnectionId &ioConnectionId, m_ioConnections.keys()) {
|
||||
IOConnection ioConnection = m_ioConnections.value(ioConnectionId);
|
||||
if (ioConnection.inputThingId() == thing->id() || ioConnection.outputThingId() == thing->id()) {
|
||||
disconnectIO(ioConnectionId);
|
||||
}
|
||||
}
|
||||
|
||||
emit thingRemoved(thingId);
|
||||
|
||||
return Thing::ThingErrorNoError;
|
||||
@ -907,6 +914,108 @@ BrowserItemActionInfo* ThingManagerImplementation::executeBrowserItemAction(cons
|
||||
return info;
|
||||
}
|
||||
|
||||
IOConnections ThingManagerImplementation::ioConnections(const ThingId &thingId) const
|
||||
{
|
||||
if (thingId.isNull()) {
|
||||
return m_ioConnections.values();
|
||||
}
|
||||
IOConnections ioConnections;
|
||||
foreach (const IOConnection &ioConnection, m_ioConnections) {
|
||||
if (ioConnection.inputThingId() == thingId || ioConnection.outputThingId() == thingId) {
|
||||
ioConnections.append(ioConnection);
|
||||
}
|
||||
}
|
||||
return ioConnections;
|
||||
}
|
||||
|
||||
Thing::ThingError ThingManagerImplementation::connectIO(const IOConnection &connection)
|
||||
{
|
||||
// Do some sanity checks
|
||||
Thing *inputThing = m_configuredThings.value(connection.inputThingId());
|
||||
if (!inputThing) {
|
||||
qCWarning(dcThingManager()) << "Could not find inputThing" << connection.inputThingId() << "configured things. Not adding IO connection.";
|
||||
return Thing::ThingErrorThingNotFound;
|
||||
}
|
||||
if (!inputThing->thingClass().stateTypes().contains(connection.inputStateTypeId())) {
|
||||
qCWarning(dcThingManager()) << "Input thing" << inputThing->name() << "does not have a state with id" << connection.inputStateTypeId();
|
||||
return Thing::ThingErrorStateTypeNotFound;
|
||||
}
|
||||
StateType inputStateType = inputThing->thingClass().stateTypes().findById(connection.inputStateTypeId());
|
||||
|
||||
// Check if this is actually an input
|
||||
if (inputStateType.ioType() != Types::IOTypeDigitalInput && inputStateType.ioType() != Types::IOTypeAnalogInput) {
|
||||
qCWarning(dcThingManager()) << "The given input state is neither a digital nor an analog input.";
|
||||
return Thing::ThingErrorInvalidParameter;
|
||||
}
|
||||
|
||||
Thing *outputThing = m_configuredThings.value(connection.outputThingId());
|
||||
if (!outputThing) {
|
||||
qCWarning(dcThingManager()) << "Could not find outputThing" << connection.outputThingId() << "configured things. Not adding IO connection.";
|
||||
return Thing::ThingErrorThingNotFound;
|
||||
}
|
||||
if (!outputThing->thingClass().stateTypes().contains(connection.outputStateTypeId())) {
|
||||
qCWarning(dcThingManager()) << "Output thing" << outputThing->name() << "does not have a state with id" << connection.outputStateTypeId();
|
||||
return Thing::ThingErrorStateTypeNotFound;
|
||||
}
|
||||
StateType outputStateType = outputThing->thingClass().stateTypes().findById(connection.outputStateTypeId());
|
||||
|
||||
// Check if this is actually an output
|
||||
if (outputStateType.ioType() != Types::IOTypeDigitalOutput && outputStateType.ioType() != Types::IOTypeAnalogOutput) {
|
||||
qCWarning(dcThingManager()) << "The given output state is neither a digital nor an analog output.";
|
||||
return Thing::ThingErrorInvalidParameter;
|
||||
}
|
||||
|
||||
// Check if io types are compatible
|
||||
if (inputStateType.ioType() == Types::IOTypeDigitalInput && outputStateType.ioType() != Types::IOTypeDigitalOutput) {
|
||||
qCWarning(dcThingManager()) << "Cannot connect IOs of different type:" << inputStateType.ioType() << "is not compatible with" << outputStateType.ioType();
|
||||
return Thing::ThingErrorInvalidParameter;
|
||||
}
|
||||
if (inputStateType.ioType() == Types::IOTypeAnalogInput && outputStateType.ioType() != Types::IOTypeAnalogOutput) {
|
||||
qCWarning(dcThingManager()) << "Cannot connect IOs of different type:" << inputStateType.ioType() << "is not compatible with" << outputStateType.ioType();
|
||||
return Thing::ThingErrorInvalidParameter;
|
||||
}
|
||||
|
||||
// Check if either input or output is already connected
|
||||
foreach (const IOConnectionId &id, m_ioConnections.keys()) {
|
||||
if (m_ioConnections.value(id).inputThingId() == connection.inputThingId() && m_ioConnections.value(id).inputStateTypeId() == connection.inputStateTypeId()) {
|
||||
qCDebug(dcThingManager()).nospace() << "Thing " << inputThing->name() << " already has an IO connection on " << inputStateType.displayName() << ". Replacing old connection.";
|
||||
disconnectIO(id);
|
||||
continue;
|
||||
}
|
||||
if (m_ioConnections.value(id).outputThingId() == connection.outputThingId() && m_ioConnections.value(id).outputStateTypeId() == connection.outputStateTypeId()) {
|
||||
qCDebug(dcThingManager()).nospace() << "Thing " << inputThing->name() << " already has an IO connection on " << inputStateType.displayName() << ". Replacing old connection.";
|
||||
disconnectIO(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally add the connection
|
||||
m_ioConnections.insert(connection.id(), connection);
|
||||
|
||||
storeIOConnections();
|
||||
|
||||
emit ioConnectionAdded(connection);
|
||||
return Thing::ThingErrorNoError;
|
||||
}
|
||||
|
||||
Thing::ThingError ThingManagerImplementation::disconnectIO(const IOConnectionId &ioConnectionId)
|
||||
{
|
||||
if (!m_ioConnections.contains(ioConnectionId)) {
|
||||
qCWarning(dcThingManager()) << "IO connection" << ioConnectionId << "not found. Cannot disconnect.";
|
||||
return Thing::ThingErrorItemNotFound;
|
||||
}
|
||||
m_ioConnections.remove(ioConnectionId);
|
||||
|
||||
NymeaSettings settings(NymeaSettings::SettingsRoleIOConnections);
|
||||
settings.beginGroup("IOConnections");
|
||||
settings.remove(ioConnectionId.toString());
|
||||
settings.endGroup();
|
||||
|
||||
qCDebug(dcThingManager()) << "IO connection disconnected:" << ioConnectionId;
|
||||
|
||||
emit ioConnectionRemoved(ioConnectionId);
|
||||
return Thing::ThingErrorNoError;
|
||||
}
|
||||
|
||||
QString ThingManagerImplementation::translate(const PluginId &pluginId, const QString &string, const QLocale &locale)
|
||||
{
|
||||
return m_translator->translate(pluginId, string, locale);
|
||||
@ -1423,6 +1532,8 @@ void ThingManagerImplementation::loadConfiguredThings()
|
||||
postSetupThing(info->thing());
|
||||
});
|
||||
}
|
||||
|
||||
loadIOConnections();
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::storeConfiguredThings()
|
||||
@ -1611,6 +1722,115 @@ void ThingManagerImplementation::slotThingStateValueChanged(const StateTypeId &s
|
||||
Param valueParam(ParamTypeId(stateTypeId.toString()), value);
|
||||
Event event(EventTypeId(stateTypeId.toString()), thing->id(), ParamList() << valueParam, true);
|
||||
emit eventTriggered(event);
|
||||
|
||||
foreach (const IOConnection &ioConnection, m_ioConnections) {
|
||||
// Check if this state is an input to an IO connection.
|
||||
if (ioConnection.inputThingId() == thing->id() && ioConnection.inputStateTypeId() == stateTypeId) {
|
||||
Thing *outputThing = m_configuredThings.value(ioConnection.outputThingId());
|
||||
if (!outputThing) {
|
||||
qCWarning(dcThingManager()) << "IO connection contains invalid output thing!";
|
||||
continue;
|
||||
}
|
||||
IntegrationPlugin *plugin = m_integrationPlugins.value(outputThing->pluginId());
|
||||
if (!plugin) {
|
||||
qCWarning(dcThingManager()) << "Plugin not found for IO connection's output action.";
|
||||
continue;
|
||||
}
|
||||
StateType inputStateType = thing->thingClass().getStateType(stateTypeId);
|
||||
|
||||
StateType outputStateType = outputThing->thingClass().getStateType(ioConnection.outputStateTypeId());
|
||||
if (outputStateType.id().isNull()) {
|
||||
qCWarning(dcThingManager()) << "Could not find output state type for IO connection.";
|
||||
continue;
|
||||
}
|
||||
QVariant outputValue;
|
||||
if (outputStateType.ioType() == Types::IOTypeDigitalOutput) {
|
||||
// Digital IOs are mapped as-is
|
||||
outputValue = value;
|
||||
|
||||
// We're already in sync! Skipping action.
|
||||
if (outputThing->stateValue(outputStateType.id()) == outputValue) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Analog IOs are mapped within the according min/max ranges
|
||||
outputValue = mapValue(value, inputStateType, outputStateType);
|
||||
|
||||
// We're already in sync (fuzzy, good enough)! Skipping action.
|
||||
if (qFuzzyCompare(outputThing->stateValue(outputStateType.id()).toDouble(), outputValue.toDouble())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Action outputAction(ActionTypeId(ioConnection.outputStateTypeId()), ioConnection.outputThingId());
|
||||
|
||||
Param outputParam(ioConnection.outputStateTypeId(), outputValue);
|
||||
outputAction.setParams(ParamList() << outputParam);
|
||||
qCDebug(dcThingManager()) << "Executing IO connection action on" << outputThing->name() << outputParam;
|
||||
ThingActionInfo* info = executeAction(outputAction);
|
||||
connect(info, &ThingActionInfo::finished, this, [=](){
|
||||
if (info->status() != Thing::ThingErrorNoError) {
|
||||
// An error happened... let's switch the input back to be in sync with the output
|
||||
qCWarning(dcThingManager()) << "Error syncing IO connection state. Reverting input back to old value.";
|
||||
if (inputStateType.ioType() == Types::IOTypeDigitalInput) {
|
||||
thing->setStateValue(inputStateType.id(), outputThing->stateValue(outputStateType.id()));
|
||||
} else {
|
||||
thing->setStateValue(inputStateType.id(), mapValue(outputThing->stateValue(outputStateType.id()), outputStateType, inputStateType));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Now check if this is an output state type and - if possible - update the inputs for bidirectional connections
|
||||
if (ioConnection.outputThingId() == thing->id() && ioConnection.outputStateTypeId() == stateTypeId) {
|
||||
Thing *inputThing = m_configuredThings.value(ioConnection.inputThingId());
|
||||
if (!inputThing) {
|
||||
qCWarning(dcThingManager()) << "IO connection contains invalid input thing!";
|
||||
continue;
|
||||
}
|
||||
IntegrationPlugin *plugin = m_integrationPlugins.value(inputThing->pluginId());
|
||||
if (!plugin) {
|
||||
qCWarning(dcThingManager()) << "Plugin not found for IO connection's input action.";
|
||||
continue;
|
||||
}
|
||||
StateType outputStateType = thing->thingClass().getStateType(stateTypeId);
|
||||
|
||||
StateType inputStateType = inputThing->thingClass().getStateType(ioConnection.inputStateTypeId());
|
||||
if (inputStateType.id().isNull()) {
|
||||
qCWarning(dcThingManager()) << "Could not find input state type for IO connection.";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!inputStateType.writable()) {
|
||||
qCDebug(dcThingManager()) << "Input state is not writable. This connection is unidirectional.";
|
||||
continue;
|
||||
}
|
||||
|
||||
QVariant inputValue;
|
||||
if (inputStateType.ioType() == Types::IOTypeDigitalInput) {
|
||||
// Digital IOs are mapped as-is
|
||||
inputValue = value;
|
||||
|
||||
// Prevent looping
|
||||
if (inputThing->stateValue(inputStateType.id()) == inputValue) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Analog IOs are mapped within the according min/max ranges
|
||||
inputValue = mapValue(value, outputStateType, inputStateType);
|
||||
|
||||
// Prevent looping even if the above calculation has rounding errors... Just skip this action if we're close enough already
|
||||
if (qFuzzyCompare(inputThing->stateValue(inputStateType.id()).toDouble(), inputValue.toDouble())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Action inputAction(ActionTypeId(ioConnection.inputStateTypeId()), ioConnection.inputThingId());
|
||||
|
||||
Param inputParam(ioConnection.inputStateTypeId(), inputValue);
|
||||
inputAction.setParams(ParamList() << inputParam);
|
||||
qCDebug(dcThingManager()) << "Executing reverse IO connection action on" << inputThing->name() << inputParam;
|
||||
executeAction(inputAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::slotThingSettingChanged(const ParamTypeId ¶mTypeId, const QVariant &value)
|
||||
@ -1756,6 +1976,53 @@ void ThingManagerImplementation::loadThingStates(Thing *thing)
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::storeIOConnections()
|
||||
{
|
||||
NymeaSettings connectionSettings(NymeaSettings::SettingsRoleIOConnections);
|
||||
connectionSettings.beginGroup("IOConnections");
|
||||
foreach (const IOConnection &ioConnection, m_ioConnections) {
|
||||
connectionSettings.beginGroup(ioConnection.id().toString());
|
||||
|
||||
connectionSettings.setValue("inputThingId", ioConnection.inputThingId().toString());
|
||||
connectionSettings.setValue("inputStateTypeId", ioConnection.inputStateTypeId().toString());
|
||||
connectionSettings.setValue("outputThingId", ioConnection.outputThingId().toString());
|
||||
connectionSettings.setValue("outputStateTypeId", ioConnection.outputStateTypeId().toString());
|
||||
|
||||
connectionSettings.endGroup();
|
||||
}
|
||||
connectionSettings.endGroup();
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::loadIOConnections()
|
||||
{
|
||||
NymeaSettings connectionSettings(NymeaSettings::SettingsRoleIOConnections);
|
||||
connectionSettings.beginGroup("IOConnections");
|
||||
foreach (const QString &idString, connectionSettings.childGroups()) {
|
||||
connectionSettings.beginGroup(idString);
|
||||
IOConnectionId id(idString);
|
||||
ThingId inputThingId = connectionSettings.value("inputThingId").toUuid();
|
||||
StateTypeId inputStateTypeId = connectionSettings.value("inputStateTypeId").toUuid();
|
||||
ThingId outputThingId = connectionSettings.value("outputThingId").toUuid();
|
||||
StateTypeId outputStateTypeId = connectionSettings.value("outputStateTypeId").toUuid();
|
||||
IOConnection ioConnection(id, inputThingId, inputStateTypeId, outputThingId, outputStateTypeId);
|
||||
m_ioConnections.insert(id, ioConnection);
|
||||
connectionSettings.endGroup();
|
||||
}
|
||||
connectionSettings.endGroup();
|
||||
}
|
||||
|
||||
QVariant ThingManagerImplementation::mapValue(const QVariant &value, const StateType &fromStateType, const StateType &toStateType) const
|
||||
{
|
||||
double fromMin = fromStateType.minValue().toDouble();
|
||||
double fromMax = fromStateType.maxValue().toDouble();
|
||||
double toMin = toStateType.minValue().toDouble();
|
||||
double toMax = toStateType.maxValue().toDouble();
|
||||
double fromValue = value.toDouble();
|
||||
double fromPercent = (fromValue - fromMin) / (fromMax - fromMin);
|
||||
double toValue = toMin + (toMax - toMin) * fromPercent;
|
||||
return toValue;
|
||||
}
|
||||
|
||||
void ThingManagerImplementation::storeThingStates(Thing *thing)
|
||||
{
|
||||
NymeaSettings settings(NymeaSettings::SettingsRoleThingStates);
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#include "integrations/thing.h"
|
||||
#include "integrations/thingdescriptor.h"
|
||||
#include "integrations/pluginmetadata.h"
|
||||
#include "integrations/ioconnection.h"
|
||||
|
||||
#include "types/thingclass.h"
|
||||
#include "types/interface.h"
|
||||
@ -113,6 +114,10 @@ public:
|
||||
BrowserActionInfo *executeBrowserItem(const BrowserAction &browserAction) override;
|
||||
BrowserItemActionInfo *executeBrowserItemAction(const BrowserItemAction &browserItemAction) override;
|
||||
|
||||
IOConnections ioConnections(const ThingId &thingId = ThingId()) const override;
|
||||
Thing::ThingError connectIO(const IOConnection &connection) override;
|
||||
Thing::ThingError disconnectIO(const IOConnectionId &ioConnectionId) override;
|
||||
|
||||
QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) override;
|
||||
ParamType translateParamType(const PluginId &pluginId, const ParamType ¶mType, const QLocale &locale) override;
|
||||
ThingClass translateThingClass(const ThingClass &thingClass, const QLocale &locale) override;
|
||||
@ -149,6 +154,10 @@ private:
|
||||
void postSetupThing(Thing *thing);
|
||||
void storeThingStates(Thing *thing);
|
||||
void loadThingStates(Thing *thing);
|
||||
void storeIOConnections();
|
||||
void loadIOConnections();
|
||||
|
||||
QVariant mapValue(const QVariant &value, const StateType &fromStateType, const StateType &toStateType) const;
|
||||
|
||||
private:
|
||||
HardwareManager *m_hardwareManager;
|
||||
@ -173,6 +182,8 @@ private:
|
||||
QString thingName;
|
||||
};
|
||||
QHash<PairingTransactionId, PairingContext> m_pendingPairings;
|
||||
|
||||
QHash<IOConnectionId, IOConnection> m_ioConnections;
|
||||
};
|
||||
|
||||
#endif // THINGMANAGERIMPLEMENTATION_H
|
||||
|
||||
@ -60,6 +60,7 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
||||
registerEnum<DeviceClass::CreateMethod, DeviceClass::CreateMethods>();
|
||||
registerEnum<Types::Unit>();
|
||||
registerEnum<Types::InputType>();
|
||||
registerEnum<Types::IOType>();
|
||||
registerEnum<RuleEngine::RemovePolicy>();
|
||||
registerEnum<BrowserItem::BrowserIcon>();
|
||||
registerEnum<MediaBrowserItem::MediaBrowserIcon>();
|
||||
|
||||
@ -59,6 +59,7 @@ IntegrationsHandler::IntegrationsHandler(ThingManager *thingManager, QObject *pa
|
||||
registerEnum<ThingClass::CreateMethod, ThingClass::CreateMethods>();
|
||||
registerEnum<Types::Unit>();
|
||||
registerEnum<Types::InputType>();
|
||||
registerEnum<Types::IOType>();
|
||||
registerEnum<RuleEngine::RemovePolicy>();
|
||||
registerEnum<BrowserItem::BrowserIcon>();
|
||||
registerEnum<MediaBrowserItem::MediaBrowserIcon>();
|
||||
@ -77,6 +78,7 @@ IntegrationsHandler::IntegrationsHandler(ThingManager *thingManager, QObject *pa
|
||||
registerObject<Action>();
|
||||
registerObject<State, States>();
|
||||
registerUncreatableObject<Thing, Things>();
|
||||
registerObject<IOConnection, IOConnections>();
|
||||
|
||||
// Registering browseritem manually for now. Not sure how to deal with the
|
||||
// polymorphism in it (e.g MediaBrowserItem)
|
||||
@ -346,6 +348,28 @@ IntegrationsHandler::IntegrationsHandler(ThingManager *thingManager, QObject *pa
|
||||
returns.insert("o:displayMessage", enumValueName(String));
|
||||
registerMethod("ExecuteBrowserItemAction", description, params, returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Fetch IO connections. Optionally filtered by thingId and stateTypeId.";
|
||||
params.insert("o:thingId", enumValueName(Uuid));
|
||||
returns.insert("ioConnections", objectRef<IOConnections>());
|
||||
registerMethod("GetIOConnections", description, params, returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Connect two generic IO states.";
|
||||
params.insert("inputThingId", enumValueName(Uuid));
|
||||
params.insert("inputStateTypeId", enumValueName(Uuid));
|
||||
params.insert("outputThingId", enumValueName(Uuid));
|
||||
params.insert("outputStateTypeId", enumValueName(Uuid));
|
||||
returns.insert("thingError", enumRef<Thing::ThingError>());
|
||||
registerMethod("ConnectIO", description, params, returns);
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Disconnect an existing IO connection.";
|
||||
params.insert("ioConnectionId", enumValueName(Uuid));
|
||||
returns.insert("thingError", enumRef<Thing::ThingError>());
|
||||
registerMethod("DisconnectIO", description, params, returns);
|
||||
|
||||
|
||||
// Notifications
|
||||
params.clear(); returns.clear();
|
||||
description = "Emitted whenever a state of a thing changes.";
|
||||
@ -392,6 +416,26 @@ IntegrationsHandler::IntegrationsHandler(ThingManager *thingManager, QObject *pa
|
||||
emit EventTriggered(params);
|
||||
});
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Emitted whenever a IO connection is added.";
|
||||
params.insert("ioConnection", objectRef<IOConnection>());
|
||||
registerNotification("IOConnectionAdded", description, params);
|
||||
connect(m_thingManager, &ThingManager::ioConnectionAdded, this, [this](const IOConnection &connection) {
|
||||
QVariantMap params;
|
||||
params.insert("ioConnection", pack(connection));
|
||||
emit IOConnectionAdded(params);
|
||||
});
|
||||
|
||||
params.clear(); returns.clear();
|
||||
description = "Emitted whenever a IO connection is removed.";
|
||||
params.insert("ioConnectionId", enumValueName(Uuid));
|
||||
registerNotification("IOConnectionRemoved", description, params);
|
||||
connect(m_thingManager, &ThingManager::ioConnectionRemoved, this, [this](const IOConnectionId &ioConnectionId) {
|
||||
QVariantMap params;
|
||||
params.insert("ioConnectionId", ioConnectionId);
|
||||
emit IOConnectionRemoved(params);
|
||||
});
|
||||
|
||||
connect(NymeaCore::instance(), &NymeaCore::pluginConfigChanged, this, &IntegrationsHandler::pluginConfigChanged);
|
||||
connect(NymeaCore::instance(), &NymeaCore::thingStateChanged, this, &IntegrationsHandler::thingStateChanged);
|
||||
connect(NymeaCore::instance(), &NymeaCore::thingRemoved, this, &IntegrationsHandler::thingRemovedNotification);
|
||||
@ -930,6 +974,33 @@ JsonReply *IntegrationsHandler::ExecuteBrowserItemAction(const QVariantMap ¶
|
||||
return jsonReply;
|
||||
}
|
||||
|
||||
JsonReply *IntegrationsHandler::GetIOConnections(const QVariantMap ¶ms)
|
||||
{
|
||||
ThingId thingId = params.value("thingId").toUuid();
|
||||
IOConnections ioConnections = m_thingManager->ioConnections(thingId);
|
||||
QVariantMap returns;
|
||||
QVariant bla = pack(ioConnections);
|
||||
returns.insert("ioConnections", pack(ioConnections));
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
JsonReply *IntegrationsHandler::ConnectIO(const QVariantMap ¶ms)
|
||||
{
|
||||
ThingId inputThingId = params.value("inputThingId").toUuid();
|
||||
StateTypeId inputStateTypeId = params.value("inputStateTypeId").toUuid();
|
||||
ThingId outputThingId = params.value("outputThingId").toUuid();
|
||||
StateTypeId outputStateTypeId = params.value("outputStateTypeId").toUuid();
|
||||
Thing::ThingError error = m_thingManager->connectIO(inputThingId, inputStateTypeId, outputThingId, outputStateTypeId);
|
||||
return createReply(statusToReply(error));
|
||||
}
|
||||
|
||||
JsonReply *IntegrationsHandler::DisconnectIO(const QVariantMap ¶ms)
|
||||
{
|
||||
IOConnectionId ioConnectionId = params.value("ioConnectionId").toUuid();
|
||||
Thing::ThingError error = m_thingManager->disconnectIO(ioConnectionId);
|
||||
return createReply(statusToReply(error));
|
||||
}
|
||||
|
||||
QVariantMap IntegrationsHandler::packBrowserItem(const BrowserItem &item)
|
||||
{
|
||||
QVariantMap ret;
|
||||
|
||||
@ -72,6 +72,10 @@ public:
|
||||
Q_INVOKABLE JsonReply *ExecuteBrowserItem(const QVariantMap ¶ms, const JsonContext &context);
|
||||
Q_INVOKABLE JsonReply *ExecuteBrowserItemAction(const QVariantMap ¶ms, const JsonContext &context);
|
||||
|
||||
Q_INVOKABLE JsonReply *GetIOConnections(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply *ConnectIO(const QVariantMap ¶ms);
|
||||
Q_INVOKABLE JsonReply *DisconnectIO(const QVariantMap ¶ms);
|
||||
|
||||
static QVariantMap packBrowserItem(const BrowserItem &item);
|
||||
|
||||
signals:
|
||||
@ -82,6 +86,8 @@ signals:
|
||||
void ThingChanged(const QVariantMap ¶ms);
|
||||
void ThingSettingChanged(const QVariantMap ¶ms);
|
||||
void EventTriggered(const QVariantMap ¶ms);
|
||||
void IOConnectionAdded(const QVariantMap ¶ms);
|
||||
void IOConnectionRemoved(const QVariantMap ¶ms);
|
||||
|
||||
private slots:
|
||||
void pluginConfigChanged(const PluginId &id, const ParamList &config);
|
||||
|
||||
@ -424,7 +424,7 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
||||
} else if (ruleActionParam.isStateBased()) {
|
||||
Thing *stateThing = m_thingManager->findConfiguredThing(ruleActionParam.stateThingId());
|
||||
if (!stateThing) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot find thing" << ruleActionParam.stateThingId() << "required by rule action" << ruleAction.id();
|
||||
qCWarning(dcRuleEngine()) << "Cannot find thing" << ruleActionParam.stateThingId() << "required by rule action";
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
@ -438,7 +438,7 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
qCWarning(dcRuleEngine()) << "Not executing rule action" << ruleAction.id();
|
||||
qCWarning(dcRuleEngine()) << "Not executing rule action";
|
||||
continue;
|
||||
}
|
||||
Action action(actionTypeId, thing->id());
|
||||
@ -476,7 +476,7 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
||||
} else if (ruleActionParam.isStateBased()) {
|
||||
Thing *stateThing = m_thingManager->findConfiguredThing(ruleActionParam.stateThingId());
|
||||
if (!stateThing) {
|
||||
qCWarning(dcRuleEngine()) << "Cannot find thing" << ruleActionParam.stateThingId() << "required by rule action" << ruleAction.id();
|
||||
qCWarning(dcRuleEngine()) << "Cannot find thing" << ruleActionParam.stateThingId() << "required by rule action";
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
@ -490,7 +490,7 @@ void NymeaCore::executeRuleActions(const QList<RuleAction> ruleActions)
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
qCWarning(dcRuleEngine()) << "Not executing rule action" << ruleAction.id();
|
||||
qCWarning(dcRuleEngine()) << "Not executing rule action";
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "ruleaction.h"
|
||||
|
||||
RuleAction::RuleAction(const ActionTypeId &actionTypeId, const ThingId &thingId, const RuleActionParams ¶ms):
|
||||
m_id(ActionId::createActionId()),
|
||||
m_thingId(thingId),
|
||||
m_actionTypeId(actionTypeId),
|
||||
m_ruleActionParams(params)
|
||||
@ -55,7 +54,6 @@ RuleAction::RuleAction(const ThingId &thingId, const QString &browserItemId):
|
||||
}
|
||||
|
||||
RuleAction::RuleAction(const RuleAction &other) :
|
||||
m_id(other.id()),
|
||||
m_thingId(other.thingId()),
|
||||
m_actionTypeId(other.actionTypeId()),
|
||||
m_browserItemId(other.browserItemId()),
|
||||
@ -66,11 +64,6 @@ RuleAction::RuleAction(const RuleAction &other) :
|
||||
|
||||
}
|
||||
|
||||
ActionId RuleAction::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool RuleAction::isValid() const
|
||||
{
|
||||
return (!m_actionTypeId.isNull() && !m_thingId.isNull())
|
||||
@ -211,7 +204,6 @@ RuleActionParam RuleAction::ruleActionParam(const QString &ruleActionParamName)
|
||||
|
||||
void RuleAction::operator=(const RuleAction &other)
|
||||
{
|
||||
m_id = other.id();
|
||||
m_actionTypeId = other.actionTypeId();
|
||||
m_ruleActionParams = other.ruleActionParams();
|
||||
}
|
||||
|
||||
@ -58,7 +58,6 @@ public:
|
||||
explicit RuleAction(const ThingId &thingId, const QString &browserItemId);
|
||||
RuleAction(const RuleAction &other);
|
||||
|
||||
ActionId id() const;
|
||||
bool isValid() const;
|
||||
|
||||
Type type() const;
|
||||
@ -92,7 +91,6 @@ public:
|
||||
void operator=(const RuleAction &other);
|
||||
|
||||
private:
|
||||
ActionId m_id;
|
||||
ThingId m_thingId;
|
||||
ActionTypeId m_actionTypeId;
|
||||
QString m_browserItemId;
|
||||
|
||||
@ -201,12 +201,12 @@ QList<Rule> RuleEngine::evaluateEvent(const Event &event)
|
||||
} else {
|
||||
// Event based rule
|
||||
if (containsEvent(rule, event, thing->thingClassId())) {
|
||||
qCDebug(dcRuleEngineDebug()).nospace().noquote() << "Rule " << rule.name() << " (" << rule.id().toString() << ") contains event " << event.eventId();
|
||||
qCDebug(dcRuleEngineDebug()).nospace().noquote() << "Rule " << rule.name() << " (" << rule.id().toString() << ") contains event";
|
||||
if (rule.statesActive() && rule.timeActive()) {
|
||||
qCDebug(dcRuleEngine).nospace().noquote() << "Rule " << rule.name() << " (" + rule.id().toString() << ") contains event" << event.eventId() << "and all states match.";
|
||||
qCDebug(dcRuleEngine).nospace().noquote() << "Rule " << rule.name() << " (" + rule.id().toString() << ") contains event and all states match.";
|
||||
rules.append(rule);
|
||||
} else {
|
||||
qCDebug(dcRuleEngine).nospace().noquote() << "Rule " << rule.name() << " (" + rule.id().toString() << ") contains event" << event.eventId() << "but state are not matching.";
|
||||
qCDebug(dcRuleEngine).nospace().noquote() << "Rule " << rule.name() << " (" + rule.id().toString() << ") contains event but state are not matching.";
|
||||
rules.append(rule);
|
||||
}
|
||||
}
|
||||
|
||||
51
libnymea/integrations/ioconnection.cpp
Normal file
51
libnymea/integrations/ioconnection.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "ioconnection.h"
|
||||
|
||||
IOConnection::IOConnection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IOConnection::IOConnection(const IOConnectionId &id, const ThingId &inputThing, const StateTypeId &inputState, const ThingId &outputThing, const StateTypeId &outputState):
|
||||
m_id(id),
|
||||
m_inputThingId(inputThing),
|
||||
m_inputStateTypeId(inputState),
|
||||
m_outputThingId(outputThing),
|
||||
m_outputStateTypeId(outputState)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IOConnectionId IOConnection::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
ThingId IOConnection::inputThingId() const
|
||||
{
|
||||
return m_inputThingId;
|
||||
}
|
||||
|
||||
StateTypeId IOConnection::inputStateTypeId() const
|
||||
{
|
||||
return m_inputStateTypeId;
|
||||
}
|
||||
|
||||
ThingId IOConnection::outputThingId() const
|
||||
{
|
||||
return m_outputThingId;
|
||||
}
|
||||
|
||||
StateTypeId IOConnection::outputStateTypeId() const
|
||||
{
|
||||
return m_outputStateTypeId;
|
||||
}
|
||||
|
||||
QVariant IOConnections::get(int index) const
|
||||
{
|
||||
return QVariant::fromValue(at(index));
|
||||
}
|
||||
|
||||
void IOConnections::put(const QVariant &variant)
|
||||
{
|
||||
append(variant.value<IOConnection>());
|
||||
}
|
||||
55
libnymea/integrations/ioconnection.h
Normal file
55
libnymea/integrations/ioconnection.h
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef IOCONNECTION_H
|
||||
#define IOCONNECTION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QList>
|
||||
#include <QVariant>
|
||||
|
||||
#include "typeutils.h"
|
||||
|
||||
class IOConnection
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROPERTY(QUuid id READ id)
|
||||
Q_PROPERTY(QUuid inputThingId READ inputThingId)
|
||||
Q_PROPERTY(QUuid inputStateTypeId READ inputStateTypeId)
|
||||
Q_PROPERTY(QUuid outputThingId READ outputThingId)
|
||||
Q_PROPERTY(QUuid outputStateTypeId READ outputStateTypeId)
|
||||
|
||||
public:
|
||||
IOConnection();
|
||||
IOConnection(const IOConnectionId &id, const ThingId &inputThingId, const StateTypeId &inputStateTypeId, const ThingId &outputThingId, const StateTypeId &outputStateTypeId);
|
||||
|
||||
IOConnectionId id() const;
|
||||
|
||||
ThingId inputThingId() const;
|
||||
StateTypeId inputStateTypeId() const;
|
||||
|
||||
ThingId outputThingId() const;
|
||||
StateTypeId outputStateTypeId() const;
|
||||
|
||||
private:
|
||||
IOConnectionId m_id;
|
||||
ThingId m_inputThingId;
|
||||
StateTypeId m_inputStateTypeId;
|
||||
ThingId m_outputThingId;
|
||||
StateTypeId m_outputStateTypeId;
|
||||
};
|
||||
|
||||
class IOConnections: public QList<IOConnection>
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROPERTY(int count READ count)
|
||||
public:
|
||||
IOConnections() {}
|
||||
inline IOConnections(std::initializer_list<IOConnection> args): QList(args) {}
|
||||
IOConnections(const QList<IOConnection> &other): QList<IOConnection>(other) {}
|
||||
Q_INVOKABLE QVariant get(int index) const;
|
||||
Q_INVOKABLE void put(const QVariant &variant);
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(IOConnection)
|
||||
Q_DECLARE_METATYPE(IOConnections)
|
||||
|
||||
|
||||
#endif // IOCONNECTION_H
|
||||
@ -381,6 +381,68 @@ void PluginMetadata::parse(const QJsonObject &jsonObject)
|
||||
if (st.contains("cached")) {
|
||||
stateType.setCached(st.value("cached").toBool());
|
||||
}
|
||||
if (st.contains("writable")) {
|
||||
stateType.setWritable(st.value("writable").toBool());
|
||||
}
|
||||
|
||||
if (st.contains("ioType")) {
|
||||
QString ioTypeString = st.value("ioType").toString();
|
||||
Types::IOType ioType = Types::IOTypeNone;
|
||||
if (ioTypeString == "digitalInput") {
|
||||
if (stateType.type() != QVariant::Bool) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as digital input but type is not \"bool\"");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
ioType = Types::IOTypeDigitalInput;
|
||||
} else if (ioTypeString == "digitalOutput") {
|
||||
if (stateType.type() != QVariant::Bool) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as digital output but type is not \"bool\"");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
if (!stateType.writable()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as digital output but is not writable");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
ioType = Types::IOTypeDigitalOutput;
|
||||
} else if (ioTypeString == "analogInput") {
|
||||
if (stateType.type() != QVariant::Double) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as analog input but type is not \"double\"");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
if (stateType.minValue().isNull() || stateType.maxValue().isNull()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as analog input but it does not define \"minValue\" and \"maxValue\"");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
ioType = Types::IOTypeAnalogInput;
|
||||
} else if (ioTypeString == "analogOutput") {
|
||||
if (stateType.type() != QVariant::Double) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as analog output but type is not \"double\"");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
if (!stateType.writable()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as analog output but is not writable");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
if (stateType.minValue().isNull() || stateType.maxValue().isNull()) {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" is marked as analog output but it does not define \"minValue\" and \"maxValue\"");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
ioType = Types::IOTypeAnalogOutput;
|
||||
} else {
|
||||
m_validationErrors.append("Thing class \"" + thingClass.name() + "\" state type \"" + stateTypeName + "\" has invalid ioType value \"" + ioType + "\" which is not any of \"digitalInput\", \"digitalOutput\", \"analogInput\" or \"analogOutput\"");
|
||||
hasError = true;
|
||||
break;
|
||||
}
|
||||
stateType.setIOType(ioType);
|
||||
}
|
||||
stateTypes.append(stateType);
|
||||
|
||||
// Events for state changed (Not checking for duplicate UUID, this is expected to be the same as the state!)
|
||||
|
||||
@ -50,3 +50,9 @@ ThingManager::ThingManager(QObject *parent) : QObject(parent)
|
||||
qRegisterMetaType<ParamType>();
|
||||
qRegisterMetaType<ParamTypes>();
|
||||
}
|
||||
|
||||
Thing::ThingError ThingManager::connectIO(const ThingId &inputThing, const StateTypeId &inputState, const ThingId &outputThing, const StateTypeId &outputState)
|
||||
{
|
||||
IOConnection connection(IOConnectionId::createIOConnectionId(), inputThing, inputState, outputThing, outputState);
|
||||
return connectIO(connection);
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
|
||||
#include "thing.h"
|
||||
#include "integrationplugin.h"
|
||||
#include "ioconnection.h"
|
||||
#include "types/interface.h"
|
||||
#include "types/vendor.h"
|
||||
#include "types/browseritem.h"
|
||||
@ -89,10 +90,18 @@ public:
|
||||
virtual BrowserActionInfo* executeBrowserItem(const BrowserAction &browserAction) = 0;
|
||||
virtual BrowserItemActionInfo* executeBrowserItemAction(const BrowserItemAction &browserItemAction) = 0;
|
||||
|
||||
virtual IOConnections ioConnections(const ThingId &thingId = ThingId()) const = 0;
|
||||
Thing::ThingError connectIO(const ThingId &inputThing, const StateTypeId &inputState, const ThingId &outputThing, const StateTypeId &outputState);
|
||||
virtual Thing::ThingError disconnectIO(const IOConnectionId &ioConnectionId) = 0;
|
||||
|
||||
virtual QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) = 0;
|
||||
virtual ParamType translateParamType(const PluginId &pluginId, const ParamType ¶mType, const QLocale &locale) = 0;
|
||||
virtual ThingClass translateThingClass(const ThingClass &thingClass, const QLocale &locale) = 0;
|
||||
virtual Vendor translateVendor(const Vendor &vendor, const QLocale &locale) = 0;
|
||||
|
||||
protected:
|
||||
virtual Thing::ThingError connectIO(const IOConnection &connection) = 0;
|
||||
|
||||
signals:
|
||||
void pluginConfigChanged(const PluginId &id, const ParamList &config);
|
||||
void eventTriggered(const Event &event);
|
||||
@ -102,6 +111,8 @@ signals:
|
||||
void thingAdded(Thing *thing);
|
||||
void thingChanged(Thing *device);
|
||||
void thingSettingChanged(const ThingId &thingId, const ParamTypeId &settingParamTypeId, const QVariant &value);
|
||||
void ioConnectionAdded(const IOConnection &ioConnection);
|
||||
void ioConnectionRemoved(const IOConnectionId &ioConnectionId);
|
||||
};
|
||||
|
||||
#endif // THINGMANAGER_H
|
||||
|
||||
@ -3,7 +3,8 @@
|
||||
"states": [
|
||||
{
|
||||
"name": "temperature",
|
||||
"type": "double"
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ HEADERS += \
|
||||
integrations/browseritemactioninfo.h \
|
||||
integrations/browseritemresult.h \
|
||||
integrations/integrationplugin.h \
|
||||
integrations/ioconnection.h \
|
||||
integrations/pluginmetadata.h \
|
||||
integrations/browseresult.h \
|
||||
integrations/thing.h \
|
||||
@ -97,6 +98,7 @@ SOURCES += \
|
||||
integrations/browseritemactioninfo.cpp \
|
||||
integrations/browseritemresult.cpp \
|
||||
integrations/integrationplugin.cpp \
|
||||
integrations/ioconnection.cpp \
|
||||
integrations/pluginmetadata.cpp \
|
||||
integrations/browseresult.cpp \
|
||||
integrations/thing.cpp \
|
||||
|
||||
@ -115,6 +115,9 @@ NymeaSettings::NymeaSettings(const SettingsRole &role, QObject *parent):
|
||||
case SettingsRoleMqttPolicies:
|
||||
fileName = "mqttpolicies.conf";
|
||||
break;
|
||||
case SettingsRoleIOConnections:
|
||||
fileName = "ioconnections.conf";
|
||||
break;
|
||||
}
|
||||
m_settings = new QSettings(basePath + settingsPrefix + fileName, QSettings::IniFormat, this);
|
||||
}
|
||||
|
||||
@ -51,6 +51,7 @@ public:
|
||||
SettingsRoleThingStates,
|
||||
SettingsRoleTags,
|
||||
SettingsRoleMqttPolicies,
|
||||
SettingsRoleIOConnections,
|
||||
};
|
||||
|
||||
explicit NymeaSettings(const SettingsRole &role = SettingsRoleNone, QObject *parent = nullptr);
|
||||
|
||||
@ -47,7 +47,6 @@
|
||||
|
||||
/*! Construct an Action with the given \a deviceId and \a actionTypeId. */
|
||||
Action::Action(const ActionTypeId &actionTypeId, const ThingId &thingId) :
|
||||
m_id(ActionId::createActionId()),
|
||||
m_actionTypeId(actionTypeId),
|
||||
m_thingId(thingId)
|
||||
{
|
||||
@ -55,19 +54,12 @@ Action::Action(const ActionTypeId &actionTypeId, const ThingId &thingId) :
|
||||
|
||||
/*! Construct a copy of an \a other Action. */
|
||||
Action::Action(const Action &other):
|
||||
m_id(other.id()),
|
||||
m_actionTypeId(other.actionTypeId()),
|
||||
m_thingId(other.thingId()),
|
||||
m_params(other.params())
|
||||
{
|
||||
}
|
||||
|
||||
/*! Returns the actionId for this Action. */
|
||||
ActionId Action::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/*! An Action is valid if actionTypeId and deviceId are valid uuids. Returns true if valid, false if not. */
|
||||
bool Action::isValid() const
|
||||
{
|
||||
@ -123,7 +115,6 @@ Param Action::param(const ParamTypeId ¶mTypeId) const
|
||||
/*! Copy the data to an \l{Action} from an \a other action. */
|
||||
void Action::operator =(const Action &other)
|
||||
{
|
||||
m_id = other.id();
|
||||
m_actionTypeId = other.actionTypeId();
|
||||
m_params = other.params();
|
||||
}
|
||||
|
||||
@ -49,8 +49,6 @@ public:
|
||||
explicit Action(const ActionTypeId &actionTypeId = ActionTypeId(), const ThingId &thingId = ThingId());
|
||||
Action(const Action &other);
|
||||
|
||||
ActionId id() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
ActionTypeId actionTypeId() const;
|
||||
@ -64,7 +62,6 @@ public:
|
||||
|
||||
void operator=(const Action &other);
|
||||
private:
|
||||
ActionId m_id;
|
||||
ActionTypeId m_actionTypeId;
|
||||
ThingId m_thingId;
|
||||
ParamList m_params;
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "browseraction.h"
|
||||
|
||||
BrowserAction::BrowserAction(const ThingId &thingId, const QString &itemId):
|
||||
m_id(ActionId::createActionId()),
|
||||
m_thingId(thingId),
|
||||
m_itemId(itemId)
|
||||
{
|
||||
@ -39,21 +38,15 @@ BrowserAction::BrowserAction(const ThingId &thingId, const QString &itemId):
|
||||
}
|
||||
|
||||
BrowserAction::BrowserAction(const BrowserAction &other):
|
||||
m_id(other.id()),
|
||||
m_thingId(other.thingId()),
|
||||
m_itemId(other.itemId())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ActionId BrowserAction::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool BrowserAction::isValid() const
|
||||
{
|
||||
return !m_id.isNull() && !m_thingId.isNull() && !m_itemId.isNull();
|
||||
return !m_thingId.isNull() && !m_itemId.isNull();
|
||||
}
|
||||
|
||||
ThingId BrowserAction::thingId() const
|
||||
@ -68,7 +61,6 @@ QString BrowserAction::itemId() const
|
||||
|
||||
void BrowserAction::operator=(const BrowserAction &other)
|
||||
{
|
||||
m_id = other.id();
|
||||
m_thingId = other.thingId();
|
||||
m_itemId = other.itemId();
|
||||
}
|
||||
|
||||
@ -39,8 +39,6 @@ public:
|
||||
explicit BrowserAction(const ThingId &thingId = ThingId(), const QString &itemId = QString());
|
||||
BrowserAction(const BrowserAction &other);
|
||||
|
||||
ActionId id() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
ThingId thingId() const;
|
||||
@ -48,7 +46,6 @@ public:
|
||||
|
||||
void operator=(const BrowserAction &other);
|
||||
private:
|
||||
ActionId m_id;
|
||||
ThingId m_thingId;
|
||||
QString m_itemId;
|
||||
};
|
||||
|
||||
@ -32,7 +32,6 @@
|
||||
|
||||
|
||||
BrowserItemAction::BrowserItemAction(const ThingId &thingId, const QString &itemId, const ActionTypeId &actionTypeId, const ParamList ¶ms):
|
||||
m_id(ActionId::createActionId()),
|
||||
m_thingId(thingId),
|
||||
m_itemId(itemId),
|
||||
m_actionTypeId(actionTypeId),
|
||||
@ -42,7 +41,6 @@ BrowserItemAction::BrowserItemAction(const ThingId &thingId, const QString &item
|
||||
}
|
||||
|
||||
BrowserItemAction::BrowserItemAction(const BrowserItemAction &other):
|
||||
m_id(other.id()),
|
||||
m_thingId(other.thingId()),
|
||||
m_itemId(other.itemId()),
|
||||
m_actionTypeId(other.actionTypeId()),
|
||||
@ -51,14 +49,9 @@ BrowserItemAction::BrowserItemAction(const BrowserItemAction &other):
|
||||
|
||||
}
|
||||
|
||||
ActionId BrowserItemAction::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool BrowserItemAction::isValid() const
|
||||
{
|
||||
return !m_id.isNull() && !m_thingId.isNull() && !m_itemId.isNull();
|
||||
return !m_thingId.isNull() && !m_itemId.isNull();
|
||||
}
|
||||
|
||||
ThingId BrowserItemAction::thingId() const
|
||||
@ -83,7 +76,6 @@ ParamList BrowserItemAction::params() const
|
||||
|
||||
void BrowserItemAction::operator=(const BrowserItemAction &other)
|
||||
{
|
||||
m_id = other.id();
|
||||
m_thingId = other.thingId();
|
||||
m_itemId = other.itemId();
|
||||
m_actionTypeId = other.actionTypeId();
|
||||
|
||||
@ -40,8 +40,6 @@ public:
|
||||
explicit BrowserItemAction(const ThingId &thingId = ThingId(), const QString &itemId = QString(), const ActionTypeId &actionTypeId = ActionTypeId(), const ParamList ¶ms = ParamList());
|
||||
BrowserItemAction(const BrowserItemAction &other);
|
||||
|
||||
ActionId id() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
ThingId thingId() const;
|
||||
@ -54,7 +52,6 @@ public:
|
||||
|
||||
void operator=(const BrowserItemAction &other);
|
||||
private:
|
||||
ActionId m_id;
|
||||
ThingId m_thingId;
|
||||
QString m_itemId;
|
||||
ActionTypeId m_actionTypeId;
|
||||
|
||||
@ -46,8 +46,7 @@
|
||||
#include "event.h"
|
||||
|
||||
/*! Constructs an Event. */
|
||||
Event::Event():
|
||||
m_id(EventId::createEventId())
|
||||
Event::Event()
|
||||
{
|
||||
}
|
||||
|
||||
@ -56,7 +55,6 @@ Event::Event():
|
||||
* specifies if the \l{Event} will be autogeneratet or not. The parameters must
|
||||
* match the description in the reflecting \l{Event}. */
|
||||
Event::Event(const EventTypeId &eventTypeId, const ThingId &thingId, const ParamList ¶ms, bool isStateChangeEvent):
|
||||
m_id(EventId::createEventId()),
|
||||
m_eventTypeId(eventTypeId),
|
||||
m_thingId(thingId),
|
||||
m_params(params),
|
||||
@ -64,13 +62,6 @@ Event::Event(const EventTypeId &eventTypeId, const ThingId &thingId, const Param
|
||||
{
|
||||
}
|
||||
|
||||
/*! Returns the Id of this Event. Each newly created Event will have a new UUID generated. The id will be copied
|
||||
* in the copy constructor. */
|
||||
EventId Event::eventId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/*! Returns the id of the \l{EventType} which describes this Event. */
|
||||
EventTypeId Event::eventTypeId() const
|
||||
{
|
||||
|
||||
@ -50,8 +50,6 @@ public:
|
||||
Event();
|
||||
Event(const EventTypeId &eventTypeId, const ThingId &thingId, const ParamList ¶ms = ParamList(), bool isStateChangeEvent = false);
|
||||
|
||||
EventId eventId() const;
|
||||
|
||||
EventTypeId eventTypeId() const;
|
||||
void setEventTypeId(const EventTypeId &eventTypeId);
|
||||
|
||||
@ -67,7 +65,6 @@ public:
|
||||
bool isStateChangeEvent() const;
|
||||
|
||||
private:
|
||||
EventId m_id;
|
||||
EventTypeId m_eventTypeId;
|
||||
ThingId m_thingId;
|
||||
ParamList m_params;
|
||||
|
||||
@ -51,18 +51,11 @@ State::State()
|
||||
/*! Constructs a State reflecting the \l{StateType} given by \a stateTypeId
|
||||
* and associated with the \l{Device} given by \a deviceId */
|
||||
State::State(const StateTypeId &stateTypeId, const ThingId &deviceId):
|
||||
m_id(StateId::createStateId()),
|
||||
m_stateTypeId(stateTypeId),
|
||||
m_thingId(deviceId)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Returns the id of this State. */
|
||||
StateId State::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/*! Returns the id of the StateType describing this State. */
|
||||
StateTypeId State::stateTypeId() const
|
||||
{
|
||||
|
||||
@ -47,8 +47,6 @@ public:
|
||||
State();
|
||||
State(const StateTypeId &stateTypeId, const ThingId &deviceId);
|
||||
|
||||
StateId id() const;
|
||||
|
||||
StateTypeId stateTypeId() const;
|
||||
ThingId thingId() const;
|
||||
|
||||
@ -56,7 +54,6 @@ public:
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
private:
|
||||
StateId m_id;
|
||||
StateTypeId m_stateTypeId;
|
||||
ThingId m_thingId;
|
||||
QVariant m_value;
|
||||
|
||||
@ -172,6 +172,30 @@ void StateType::setUnit(const Types::Unit &unit)
|
||||
m_unit = unit;
|
||||
}
|
||||
|
||||
/*! Returns the IO type of this StateType. */
|
||||
Types::IOType StateType::ioType() const
|
||||
{
|
||||
return m_ioType;
|
||||
}
|
||||
|
||||
/*! Sets the IO type of this StateType. */
|
||||
void StateType::setIOType(Types::IOType ioType)
|
||||
{
|
||||
m_ioType = ioType;
|
||||
}
|
||||
|
||||
/*! Returns whether the StateType is writable or not. A writable StateType will have an according ActionType defined.*/
|
||||
bool StateType::writable() const
|
||||
{
|
||||
return m_writable;
|
||||
}
|
||||
|
||||
/*! Sets the writable property to true */
|
||||
void StateType::setWritable(bool writable)
|
||||
{
|
||||
m_writable = writable;
|
||||
}
|
||||
|
||||
/*! Returns true if this StateType is to be cached. This means, the last state value will be stored to disk upon shutdown and restored on reboot. If this is false, states will be initialized with the default value on each boot. By default all states are cached by the system. */
|
||||
bool StateType::cached() const
|
||||
{
|
||||
@ -189,7 +213,7 @@ QStringList StateType::typeProperties()
|
||||
{
|
||||
return QStringList() << "id" << "name" << "displayName" << "displayNameEvent" << "type" << "defaultValue"
|
||||
<< "cached" << "unit" << "minValue" << "maxValue" << "possibleValues" << "writable"
|
||||
<< "displayNameAction";
|
||||
<< "displayNameAction" << "ioType";
|
||||
}
|
||||
|
||||
/*! Returns a list of mandatory properties a DeviceClass definition must have. */
|
||||
@ -205,6 +229,16 @@ StateTypes::StateTypes(const QList<StateType> &other)
|
||||
}
|
||||
}
|
||||
|
||||
bool StateTypes::contains(const StateTypeId &stateTypeId)
|
||||
{
|
||||
foreach (const StateType &stateType, *this) {
|
||||
if (stateType.id() == stateTypeId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QVariant StateTypes::get(int index) const
|
||||
{
|
||||
return QVariant::fromValue(at(index));
|
||||
|
||||
@ -46,6 +46,7 @@ class LIBNYMEA_EXPORT StateType
|
||||
Q_PROPERTY(int index READ index WRITE setIndex)
|
||||
Q_PROPERTY(QVariant defaultValue READ defaultValue WRITE setDefaultValue)
|
||||
Q_PROPERTY(Types::Unit unit READ unit WRITE setUnit USER true)
|
||||
Q_PROPERTY(Types::IOType ioType READ ioType WRITE setIOType USER true)
|
||||
Q_PROPERTY(QVariant minValue READ minValue WRITE setMinValue USER true)
|
||||
Q_PROPERTY(QVariant maxValue READ maxValue WRITE setMaxValue USER true)
|
||||
Q_PROPERTY(QVariantList possibleValues READ possibleValues WRITE setPossibleValues USER true)
|
||||
@ -83,6 +84,12 @@ public:
|
||||
Types::Unit unit() const;
|
||||
void setUnit(const Types::Unit &unit);
|
||||
|
||||
Types::IOType ioType() const;
|
||||
void setIOType(Types::IOType ioType);
|
||||
|
||||
bool writable() const;
|
||||
void setWritable(bool writable);
|
||||
|
||||
bool cached() const;
|
||||
void setCached(bool cached);
|
||||
|
||||
@ -100,6 +107,8 @@ private:
|
||||
QVariant m_maxValue;
|
||||
QVariantList m_possibleValues;
|
||||
Types::Unit m_unit = Types::UnitNone;
|
||||
Types::IOType m_ioType = Types::IOTypeNone;
|
||||
bool m_writable = false;
|
||||
bool m_cached = true;
|
||||
};
|
||||
Q_DECLARE_METATYPE(StateType)
|
||||
@ -111,6 +120,7 @@ class StateTypes: public QList<StateType>
|
||||
public:
|
||||
StateTypes() = default;
|
||||
StateTypes(const QList<StateType> &other);
|
||||
bool contains(const StateTypeId &stateTypeId);
|
||||
Q_INVOKABLE QVariant get(int index) const;
|
||||
Q_INVOKABLE void put(const QVariant &variant);
|
||||
StateType findByName(const QString &name);
|
||||
|
||||
@ -56,14 +56,12 @@ DECLARE_TYPE_ID(ThingDescriptor)
|
||||
DECLARE_TYPE_ID(ParamType)
|
||||
DECLARE_TYPE_ID(Param)
|
||||
DECLARE_TYPE_ID(EventType)
|
||||
DECLARE_TYPE_ID(Event)
|
||||
DECLARE_TYPE_ID(StateType)
|
||||
DECLARE_TYPE_ID(State)
|
||||
DECLARE_TYPE_ID(ActionType)
|
||||
DECLARE_TYPE_ID(Action)
|
||||
DECLARE_TYPE_ID(Plugin)
|
||||
DECLARE_TYPE_ID(Rule)
|
||||
DECLARE_TYPE_ID(Browser)
|
||||
DECLARE_TYPE_ID(IOConnection)
|
||||
|
||||
DECLARE_TYPE_ID(PairingTransaction)
|
||||
|
||||
@ -165,6 +163,15 @@ public:
|
||||
BrowserTypeGeneric,
|
||||
};
|
||||
Q_ENUM(BrowserType)
|
||||
|
||||
enum IOType {
|
||||
IOTypeNone,
|
||||
IOTypeDigitalInput,
|
||||
IOTypeDigitalOutput,
|
||||
IOTypeAnalogInput,
|
||||
IOTypeAnalogOutput
|
||||
};
|
||||
Q_ENUM(IOType)
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Types::InputType)
|
||||
|
||||
@ -5,7 +5,7 @@ NYMEA_VERSION_STRING=$$system('dpkg-parsechangelog | sed -n -e "s/^Version: //p"
|
||||
|
||||
# define protocol versions
|
||||
JSON_PROTOCOL_VERSION_MAJOR=5
|
||||
JSON_PROTOCOL_VERSION_MINOR=0
|
||||
JSON_PROTOCOL_VERSION_MINOR=1
|
||||
JSON_PROTOCOL_VERSION="$${JSON_PROTOCOL_VERSION_MAJOR}.$${JSON_PROTOCOL_VERSION_MINOR}"
|
||||
LIBNYMEA_API_VERSION_MAJOR=5
|
||||
LIBNYMEA_API_VERSION_MINOR=0
|
||||
|
||||
@ -246,5 +246,54 @@ extern ParamTypeId inputTypeMockWritableTimestampUIntActionWritableTimestampUInt
|
||||
extern ThingClassId oAuthGoogleMockThingClassId;
|
||||
extern ThingClassId oAuthSonosMockThingClassId;
|
||||
extern ThingClassId userAndPassMockThingClassId;
|
||||
extern ThingClassId genericIoMockThingClassId;
|
||||
extern StateTypeId genericIoMockDigitalInput1StateTypeId;
|
||||
extern StateTypeId genericIoMockDigitalInput2StateTypeId;
|
||||
extern StateTypeId genericIoMockDigitalOutput1StateTypeId;
|
||||
extern StateTypeId genericIoMockDigitalOutput2StateTypeId;
|
||||
extern StateTypeId genericIoMockAnalogInput1StateTypeId;
|
||||
extern StateTypeId genericIoMockAnalogInput2StateTypeId;
|
||||
extern StateTypeId genericIoMockAnalogOutput1StateTypeId;
|
||||
extern StateTypeId genericIoMockAnalogOutput2StateTypeId;
|
||||
extern EventTypeId genericIoMockDigitalInput1EventTypeId;
|
||||
extern ParamTypeId genericIoMockDigitalInput1EventDigitalInput1ParamTypeId;
|
||||
extern EventTypeId genericIoMockDigitalInput2EventTypeId;
|
||||
extern ParamTypeId genericIoMockDigitalInput2EventDigitalInput2ParamTypeId;
|
||||
extern EventTypeId genericIoMockDigitalOutput1EventTypeId;
|
||||
extern ParamTypeId genericIoMockDigitalOutput1EventDigitalOutput1ParamTypeId;
|
||||
extern EventTypeId genericIoMockDigitalOutput2EventTypeId;
|
||||
extern ParamTypeId genericIoMockDigitalOutput2EventDigitalOutput2ParamTypeId;
|
||||
extern EventTypeId genericIoMockAnalogInput1EventTypeId;
|
||||
extern ParamTypeId genericIoMockAnalogInput1EventAnalogInput1ParamTypeId;
|
||||
extern EventTypeId genericIoMockAnalogInput2EventTypeId;
|
||||
extern ParamTypeId genericIoMockAnalogInput2EventAnalogInput2ParamTypeId;
|
||||
extern EventTypeId genericIoMockAnalogOutput1EventTypeId;
|
||||
extern ParamTypeId genericIoMockAnalogOutput1EventAnalogOutput1ParamTypeId;
|
||||
extern EventTypeId genericIoMockAnalogOutput2EventTypeId;
|
||||
extern ParamTypeId genericIoMockAnalogOutput2EventAnalogOutput2ParamTypeId;
|
||||
extern ActionTypeId genericIoMockDigitalOutput1ActionTypeId;
|
||||
extern ParamTypeId genericIoMockDigitalOutput1ActionDigitalOutput1ParamTypeId;
|
||||
extern ActionTypeId genericIoMockDigitalOutput2ActionTypeId;
|
||||
extern ParamTypeId genericIoMockDigitalOutput2ActionDigitalOutput2ParamTypeId;
|
||||
extern ActionTypeId genericIoMockAnalogInput1ActionTypeId;
|
||||
extern ParamTypeId genericIoMockAnalogInput1ActionAnalogInput1ParamTypeId;
|
||||
extern ActionTypeId genericIoMockAnalogOutput1ActionTypeId;
|
||||
extern ParamTypeId genericIoMockAnalogOutput1ActionAnalogOutput1ParamTypeId;
|
||||
extern ActionTypeId genericIoMockAnalogOutput2ActionTypeId;
|
||||
extern ParamTypeId genericIoMockAnalogOutput2ActionAnalogOutput2ParamTypeId;
|
||||
extern ThingClassId virtualIoLightMockThingClassId;
|
||||
extern StateTypeId virtualIoLightMockPowerStateTypeId;
|
||||
extern EventTypeId virtualIoLightMockPowerEventTypeId;
|
||||
extern ParamTypeId virtualIoLightMockPowerEventPowerParamTypeId;
|
||||
extern ActionTypeId virtualIoLightMockPowerActionTypeId;
|
||||
extern ParamTypeId virtualIoLightMockPowerActionPowerParamTypeId;
|
||||
extern ThingClassId virtualIoTemperatureSensorMockThingClassId;
|
||||
extern ParamTypeId virtualIoTemperatureSensorMockSettingsMinTempParamTypeId;
|
||||
extern ParamTypeId virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId;
|
||||
extern StateTypeId virtualIoTemperatureSensorMockTemperatureStateTypeId;
|
||||
extern EventTypeId virtualIoTemperatureSensorMockTemperatureEventTypeId;
|
||||
extern ParamTypeId virtualIoTemperatureSensorMockTemperatureEventTemperatureParamTypeId;
|
||||
extern ActionTypeId virtualIoTemperatureSensorMockTemperatureActionTypeId;
|
||||
extern ParamTypeId virtualIoTemperatureSensorMockTemperatureActionTemperatureParamTypeId;
|
||||
|
||||
#endif // EXTERNPLUGININFO_H
|
||||
|
||||
@ -233,6 +233,24 @@ void IntegrationPluginMock::setupThing(ThingSetupInfo *info)
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->thing()->thingClassId() == genericIoMockThingClassId) {
|
||||
qCDebug(dcMock()) << "Generic IO mock setup complete";
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->thing()->thingClassId() == virtualIoLightMockThingClassId) {
|
||||
qCDebug(dcMock()) << "Virtual IO mock light setup complete";
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->thing()->thingClassId() == virtualIoTemperatureSensorMockThingClassId) {
|
||||
qCDebug(dcMock()) << "Virtual IO mock temperature sensor setup complete";
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
|
||||
qCWarning(dcMock()) << "Unhandled thing class" << info->thing()->thingClass();
|
||||
info->finish(Thing::ThingErrorThingClassNotFound);
|
||||
}
|
||||
@ -689,9 +707,59 @@ void IntegrationPluginMock::executeAction(ThingActionInfo *info)
|
||||
info->thing()->setStateValue(inputTypeMockWritableTimestampUIntStateTypeId, info->action().param(inputTypeMockWritableTimestampUIntActionWritableTimestampUIntParamTypeId).value().toULongLong());
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
info->finish(Thing::ThingErrorThingClassNotFound);
|
||||
|
||||
if (info->thing()->thingClassId() == virtualIoLightMockThingClassId) {
|
||||
if (info->action().actionTypeId() == virtualIoLightMockPowerActionTypeId) {
|
||||
qCDebug(dcMock()) << "ExecuteAction for virtual light power action with param" << info->action().param(virtualIoLightMockPowerActionPowerParamTypeId).value();
|
||||
info->thing()->setStateValue(virtualIoLightMockPowerStateTypeId, info->action().param(virtualIoLightMockPowerActionPowerParamTypeId).value());
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->thing()->thingClassId() == genericIoMockThingClassId) {
|
||||
if (info->action().actionTypeId() == genericIoMockDigitalOutput1ActionTypeId) {
|
||||
info->thing()->setStateValue(genericIoMockDigitalOutput1StateTypeId, info->action().param(genericIoMockDigitalOutput1ActionDigitalOutput1ParamTypeId).value());
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
if (info->action().actionTypeId() == genericIoMockDigitalOutput2ActionTypeId) {
|
||||
info->thing()->setStateValue(genericIoMockDigitalOutput2StateTypeId, info->action().param(genericIoMockDigitalOutput2ActionDigitalOutput2ParamTypeId).value());
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
if (info->action().actionTypeId() == genericIoMockAnalogInput1ActionTypeId) {
|
||||
qCDebug(dcMock()) << "ExecuteAction for virtual io analog in 1 action with param" << info->action().param(genericIoMockAnalogInput1ActionAnalogInput1ParamTypeId).value();
|
||||
info->thing()->setStateValue(genericIoMockAnalogInput1StateTypeId, info->action().param(genericIoMockAnalogInput1ActionAnalogInput1ParamTypeId).value());
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
if (info->action().actionTypeId() == genericIoMockAnalogOutput1ActionTypeId) {
|
||||
info->thing()->setStateValue(genericIoMockAnalogOutput1StateTypeId, info->action().param(genericIoMockAnalogOutput1ActionAnalogOutput1ParamTypeId).value());
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
if (info->action().actionTypeId() == genericIoMockAnalogOutput2ActionTypeId) {
|
||||
info->thing()->setStateValue(genericIoMockAnalogOutput2StateTypeId, info->action().param(genericIoMockAnalogOutput2ActionAnalogOutput2ParamTypeId).value());
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (info->thing()->thingClassId() == virtualIoTemperatureSensorMockThingClassId) {
|
||||
if (info->action().actionTypeId() == virtualIoTemperatureSensorMockTemperatureActionTypeId) {
|
||||
double minTemp = info->thing()->setting(virtualIoTemperatureSensorMockSettingsMinTempParamTypeId).toDouble();
|
||||
double maxTemp = info->thing()->setting(virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId).toDouble();
|
||||
double value = info->action().param(virtualIoTemperatureSensorMockTemperatureActionTemperatureParamTypeId).value().toDouble();
|
||||
double temp = minTemp + (maxTemp - minTemp) * value;
|
||||
info->thing()->setStateValue(virtualIoTemperatureSensorMockTemperatureStateTypeId, temp);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qCWarning(dcMock()) << "Unhandled executeAction call in mock plugin!";
|
||||
}
|
||||
|
||||
void IntegrationPluginMock::executeBrowserItem(BrowserActionInfo *info)
|
||||
@ -728,7 +796,6 @@ void IntegrationPluginMock::executeBrowserItem(BrowserActionInfo *info)
|
||||
|
||||
void IntegrationPluginMock::executeBrowserItemAction(BrowserItemActionInfo *info)
|
||||
{
|
||||
qCDebug(dcMock()) << "TODO" << info << info->browserItemAction().id();
|
||||
if (info->browserItemAction().actionTypeId() == mockAddToFavoritesBrowserItemActionTypeId) {
|
||||
|
||||
VirtualFsNode *node = m_virtualFs->findNode(info->browserItemAction().itemId());
|
||||
|
||||
@ -868,6 +868,168 @@
|
||||
"displayName": "Mocked Thing (User & Password)",
|
||||
"createMethods": ["discovery", "user"],
|
||||
"setupMethod": "userandpassword"
|
||||
},
|
||||
{
|
||||
"id": "7cbd729a-465b-4ccb-b59c-5733039dbbed",
|
||||
"name": "genericIoMock",
|
||||
"displayName": "Generic IO pins",
|
||||
"createMethods": ["user"],
|
||||
"setupMethod": "justAdd",
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "07165c12-4d53-45c0-8bf1-34618443b706",
|
||||
"name": "digitalInput1",
|
||||
"displayName": "Digital input 1",
|
||||
"displayNameEvent": "Digital input 1 changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"ioType": "digitalInput"
|
||||
},
|
||||
{
|
||||
"id": "0a4362ba-a086-4540-84ba-107ef7b99ed8",
|
||||
"name": "digitalInput2",
|
||||
"displayName": "Digital input 2",
|
||||
"displayNameEvent": "Digital input 2 changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"ioType": "digitalInput"
|
||||
},
|
||||
{
|
||||
"id": "d6fcdb52-f7c3-423b-b9f5-1e29f164c42e",
|
||||
"name": "digitalOutput1",
|
||||
"displayName": "Digital Output 1",
|
||||
"displayNameEvent": "Digital Output 1 changed",
|
||||
"displayNameAction": "Set Digital Output 1",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"ioType": "digitalOutput",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "35de8b68-0cf3-4850-a27d-cf9c4a26921f",
|
||||
"name": "digitalOutput2",
|
||||
"displayName": "Digital Output 2",
|
||||
"displayNameEvent": "Digital Output 2 changed",
|
||||
"displayNameAction": "Set Digital Output 2",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"ioType": "digitalOutput",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "ac56977c-cbba-47c6-a827-5735d8b0aed6",
|
||||
"name": "analogInput1",
|
||||
"displayName": "Analog Input 1",
|
||||
"displayNameEvent": "Analog Input 1 changed",
|
||||
"type": "double",
|
||||
"defaultValue": 0,
|
||||
"ioType": "analogInput",
|
||||
"minValue": 0,
|
||||
"maxValue": 3.3,
|
||||
"writable": true,
|
||||
"displayNameAction": "Set analog input 1"
|
||||
},
|
||||
{
|
||||
"id": "8e07e57e-ba4e-42df-81ee-5b72ed074532",
|
||||
"name": "analogInput2",
|
||||
"displayName": "Analog Input 2",
|
||||
"displayNameEvent": "Analog Input 2 changed",
|
||||
"type": "double",
|
||||
"defaultValue": 0,
|
||||
"ioType": "analogInput",
|
||||
"minValue": 0,
|
||||
"maxValue": 5
|
||||
},
|
||||
{
|
||||
"id": "70cf053e-4abc-4d88-8e1e-2bd9a62256c7",
|
||||
"name": "analogOutput1",
|
||||
"displayName": "Analog Output 1",
|
||||
"displayNameEvent": "Analog Output 1 changed",
|
||||
"displayNameAction": "Set Output Input 1",
|
||||
"type": "double",
|
||||
"defaultValue": 0,
|
||||
"ioType": "analogOutput",
|
||||
"minValue": 0,
|
||||
"maxValue": 3.3,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "e40bcf7d-47b8-41fa-b213-3652a905b376",
|
||||
"name": "analogOutput2",
|
||||
"displayName": "Analog Output 2",
|
||||
"displayNameEvent": "Analog Output 2 changed",
|
||||
"displayNameAction": "Set Output Input 2",
|
||||
"type": "double",
|
||||
"defaultValue": 0,
|
||||
"ioType": "analogOutput",
|
||||
"minValue": 0,
|
||||
"maxValue": 5,
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "98ab137e-757e-43f8-9d9b-5d50d990242a",
|
||||
"name": "virtualIoLightMock",
|
||||
"displayName": "Generic Light (Mock)",
|
||||
"createMethods": ["user"],
|
||||
"setupMethod": "justAdd",
|
||||
"interfaces": ["light"],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "d1917b3d-1530-4cf9-90f7-263ee88e714b",
|
||||
"name": "power",
|
||||
"displayName": "Power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"ioType": "digitalInput",
|
||||
"writable": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "f8917e12-c9cb-4ea1-a06e-1ce6db2194f3",
|
||||
"name": "virtualIoTemperatureSensorMock",
|
||||
"displayName": "Generic Temperature Sensor (Mock)",
|
||||
"createMethods": ["user"],
|
||||
"setupMethod": "justAdd",
|
||||
"interfaces": ["temperaturesensor"],
|
||||
"settingsTypes": [
|
||||
{
|
||||
"id": "803cddbf-94c7-4f35-bc7a-18698b03b942",
|
||||
"name": "minTemp",
|
||||
"displayName": "Minimum temperature",
|
||||
"type": "double",
|
||||
"defaultValue": -20,
|
||||
"unit": "DegreeCelsius"
|
||||
},
|
||||
{
|
||||
"id": "7077c56f-c35b-4252-8c15-8fb549be04ce",
|
||||
"name": "maxTemp",
|
||||
"displayName": "Maximum temperature",
|
||||
"type": "double",
|
||||
"defaultValue": 50,
|
||||
"unit": "DegreeCelsius"
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "db9cc518-1012-47e2-8212-6e616fed07a6",
|
||||
"name": "temperature",
|
||||
"displayName": "Temperature",
|
||||
"displayNameEvent": "Temperature changed",
|
||||
"displayNameAction": "Set temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": 0,
|
||||
"ioType": "analogOutput",
|
||||
"writable": true,
|
||||
"minValue": 0,
|
||||
"maxValue": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -250,11 +250,105 @@ ParamTypeId inputTypeMockWritableTimestampUIntActionWritableTimestampUIntParamTy
|
||||
ThingClassId oAuthGoogleMockThingClassId = ThingClassId("{805d1692-7bd0-449a-9d5c-43a332ff58f4}");
|
||||
ThingClassId oAuthSonosMockThingClassId = ThingClassId("{783c615b-7bd6-49a4-98b0-8d1deb3c7156}");
|
||||
ThingClassId userAndPassMockThingClassId = ThingClassId("{6fe07a77-9c07-4736-81e2-d504314bbcb9}");
|
||||
ThingClassId genericIoMockThingClassId = ThingClassId("{7cbd729a-465b-4ccb-b59c-5733039dbbed}");
|
||||
StateTypeId genericIoMockDigitalInput1StateTypeId = StateTypeId("{07165c12-4d53-45c0-8bf1-34618443b706}");
|
||||
StateTypeId genericIoMockDigitalInput2StateTypeId = StateTypeId("{0a4362ba-a086-4540-84ba-107ef7b99ed8}");
|
||||
StateTypeId genericIoMockDigitalOutput1StateTypeId = StateTypeId("{d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}");
|
||||
StateTypeId genericIoMockDigitalOutput2StateTypeId = StateTypeId("{35de8b68-0cf3-4850-a27d-cf9c4a26921f}");
|
||||
StateTypeId genericIoMockAnalogInput1StateTypeId = StateTypeId("{ac56977c-cbba-47c6-a827-5735d8b0aed6}");
|
||||
StateTypeId genericIoMockAnalogInput2StateTypeId = StateTypeId("{8e07e57e-ba4e-42df-81ee-5b72ed074532}");
|
||||
StateTypeId genericIoMockAnalogOutput1StateTypeId = StateTypeId("{70cf053e-4abc-4d88-8e1e-2bd9a62256c7}");
|
||||
StateTypeId genericIoMockAnalogOutput2StateTypeId = StateTypeId("{e40bcf7d-47b8-41fa-b213-3652a905b376}");
|
||||
EventTypeId genericIoMockDigitalInput1EventTypeId = EventTypeId("{07165c12-4d53-45c0-8bf1-34618443b706}");
|
||||
ParamTypeId genericIoMockDigitalInput1EventDigitalInput1ParamTypeId = ParamTypeId("{07165c12-4d53-45c0-8bf1-34618443b706}");
|
||||
EventTypeId genericIoMockDigitalInput2EventTypeId = EventTypeId("{0a4362ba-a086-4540-84ba-107ef7b99ed8}");
|
||||
ParamTypeId genericIoMockDigitalInput2EventDigitalInput2ParamTypeId = ParamTypeId("{0a4362ba-a086-4540-84ba-107ef7b99ed8}");
|
||||
EventTypeId genericIoMockDigitalOutput1EventTypeId = EventTypeId("{d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}");
|
||||
ParamTypeId genericIoMockDigitalOutput1EventDigitalOutput1ParamTypeId = ParamTypeId("{d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}");
|
||||
EventTypeId genericIoMockDigitalOutput2EventTypeId = EventTypeId("{35de8b68-0cf3-4850-a27d-cf9c4a26921f}");
|
||||
ParamTypeId genericIoMockDigitalOutput2EventDigitalOutput2ParamTypeId = ParamTypeId("{35de8b68-0cf3-4850-a27d-cf9c4a26921f}");
|
||||
EventTypeId genericIoMockAnalogInput1EventTypeId = EventTypeId("{ac56977c-cbba-47c6-a827-5735d8b0aed6}");
|
||||
ParamTypeId genericIoMockAnalogInput1EventAnalogInput1ParamTypeId = ParamTypeId("{ac56977c-cbba-47c6-a827-5735d8b0aed6}");
|
||||
EventTypeId genericIoMockAnalogInput2EventTypeId = EventTypeId("{8e07e57e-ba4e-42df-81ee-5b72ed074532}");
|
||||
ParamTypeId genericIoMockAnalogInput2EventAnalogInput2ParamTypeId = ParamTypeId("{8e07e57e-ba4e-42df-81ee-5b72ed074532}");
|
||||
EventTypeId genericIoMockAnalogOutput1EventTypeId = EventTypeId("{70cf053e-4abc-4d88-8e1e-2bd9a62256c7}");
|
||||
ParamTypeId genericIoMockAnalogOutput1EventAnalogOutput1ParamTypeId = ParamTypeId("{70cf053e-4abc-4d88-8e1e-2bd9a62256c7}");
|
||||
EventTypeId genericIoMockAnalogOutput2EventTypeId = EventTypeId("{e40bcf7d-47b8-41fa-b213-3652a905b376}");
|
||||
ParamTypeId genericIoMockAnalogOutput2EventAnalogOutput2ParamTypeId = ParamTypeId("{e40bcf7d-47b8-41fa-b213-3652a905b376}");
|
||||
ActionTypeId genericIoMockDigitalOutput1ActionTypeId = ActionTypeId("{d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}");
|
||||
ParamTypeId genericIoMockDigitalOutput1ActionDigitalOutput1ParamTypeId = ParamTypeId("{d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}");
|
||||
ActionTypeId genericIoMockDigitalOutput2ActionTypeId = ActionTypeId("{35de8b68-0cf3-4850-a27d-cf9c4a26921f}");
|
||||
ParamTypeId genericIoMockDigitalOutput2ActionDigitalOutput2ParamTypeId = ParamTypeId("{35de8b68-0cf3-4850-a27d-cf9c4a26921f}");
|
||||
ActionTypeId genericIoMockAnalogInput1ActionTypeId = ActionTypeId("{ac56977c-cbba-47c6-a827-5735d8b0aed6}");
|
||||
ParamTypeId genericIoMockAnalogInput1ActionAnalogInput1ParamTypeId = ParamTypeId("{ac56977c-cbba-47c6-a827-5735d8b0aed6}");
|
||||
ActionTypeId genericIoMockAnalogOutput1ActionTypeId = ActionTypeId("{70cf053e-4abc-4d88-8e1e-2bd9a62256c7}");
|
||||
ParamTypeId genericIoMockAnalogOutput1ActionAnalogOutput1ParamTypeId = ParamTypeId("{70cf053e-4abc-4d88-8e1e-2bd9a62256c7}");
|
||||
ActionTypeId genericIoMockAnalogOutput2ActionTypeId = ActionTypeId("{e40bcf7d-47b8-41fa-b213-3652a905b376}");
|
||||
ParamTypeId genericIoMockAnalogOutput2ActionAnalogOutput2ParamTypeId = ParamTypeId("{e40bcf7d-47b8-41fa-b213-3652a905b376}");
|
||||
ThingClassId virtualIoLightMockThingClassId = ThingClassId("{98ab137e-757e-43f8-9d9b-5d50d990242a}");
|
||||
StateTypeId virtualIoLightMockPowerStateTypeId = StateTypeId("{d1917b3d-1530-4cf9-90f7-263ee88e714b}");
|
||||
EventTypeId virtualIoLightMockPowerEventTypeId = EventTypeId("{d1917b3d-1530-4cf9-90f7-263ee88e714b}");
|
||||
ParamTypeId virtualIoLightMockPowerEventPowerParamTypeId = ParamTypeId("{d1917b3d-1530-4cf9-90f7-263ee88e714b}");
|
||||
ActionTypeId virtualIoLightMockPowerActionTypeId = ActionTypeId("{d1917b3d-1530-4cf9-90f7-263ee88e714b}");
|
||||
ParamTypeId virtualIoLightMockPowerActionPowerParamTypeId = ParamTypeId("{d1917b3d-1530-4cf9-90f7-263ee88e714b}");
|
||||
ThingClassId virtualIoTemperatureSensorMockThingClassId = ThingClassId("{f8917e12-c9cb-4ea1-a06e-1ce6db2194f3}");
|
||||
ParamTypeId virtualIoTemperatureSensorMockSettingsMinTempParamTypeId = ParamTypeId("{803cddbf-94c7-4f35-bc7a-18698b03b942}");
|
||||
ParamTypeId virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId = ParamTypeId("{7077c56f-c35b-4252-8c15-8fb549be04ce}");
|
||||
StateTypeId virtualIoTemperatureSensorMockTemperatureStateTypeId = StateTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||
EventTypeId virtualIoTemperatureSensorMockTemperatureEventTypeId = EventTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||
ParamTypeId virtualIoTemperatureSensorMockTemperatureEventTemperatureParamTypeId = ParamTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||
ActionTypeId virtualIoTemperatureSensorMockTemperatureActionTypeId = ActionTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||
ParamTypeId virtualIoTemperatureSensorMockTemperatureActionTemperatureParamTypeId = ParamTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||
|
||||
const QString translations[] {
|
||||
//: The name of the Browser Item ActionType ({00b8f0a8-99ca-4aa4-833d-59eb8d4d6de3}) of ThingClass mock
|
||||
QT_TRANSLATE_NOOP("mock", "Add to favorites"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, ActionType: analogInput1, ID: {ac56977c-cbba-47c6-a827-5735d8b0aed6})
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Input 1"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: analogInput1, ID: {ac56977c-cbba-47c6-a827-5735d8b0aed6})
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Input 1"),
|
||||
|
||||
//: The name of the StateType ({ac56977c-cbba-47c6-a827-5735d8b0aed6}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Input 1"),
|
||||
|
||||
//: The name of the EventType ({ac56977c-cbba-47c6-a827-5735d8b0aed6}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Input 1 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: analogInput2, ID: {8e07e57e-ba4e-42df-81ee-5b72ed074532})
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Input 2"),
|
||||
|
||||
//: The name of the StateType ({8e07e57e-ba4e-42df-81ee-5b72ed074532}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Input 2"),
|
||||
|
||||
//: The name of the EventType ({8e07e57e-ba4e-42df-81ee-5b72ed074532}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Input 2 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, ActionType: analogOutput1, ID: {70cf053e-4abc-4d88-8e1e-2bd9a62256c7})
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 1"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: analogOutput1, ID: {70cf053e-4abc-4d88-8e1e-2bd9a62256c7})
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 1"),
|
||||
|
||||
//: The name of the StateType ({70cf053e-4abc-4d88-8e1e-2bd9a62256c7}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 1"),
|
||||
|
||||
//: The name of the EventType ({70cf053e-4abc-4d88-8e1e-2bd9a62256c7}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 1 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, ActionType: analogOutput2, ID: {e40bcf7d-47b8-41fa-b213-3652a905b376})
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 2"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: analogOutput2, ID: {e40bcf7d-47b8-41fa-b213-3652a905b376})
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 2"),
|
||||
|
||||
//: The name of the StateType ({e40bcf7d-47b8-41fa-b213-3652a905b376}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 2"),
|
||||
|
||||
//: The name of the EventType ({e40bcf7d-47b8-41fa-b213-3652a905b376}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Analog Output 2 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: inputTypeMock, EventType: bool, ID: {3bad3a09-5826-4ed7-a832-10e3e2ee2a7d})
|
||||
QT_TRANSLATE_NOOP("mock", "Bool"),
|
||||
|
||||
@ -273,6 +367,48 @@ const QString translations[] {
|
||||
//: The name of the EventType ({4507d5c6-b692-4bd6-87f2-00364bc0cb4d}) of ThingClass inputTypeMock
|
||||
QT_TRANSLATE_NOOP("mock", "Color changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, ActionType: digitalOutput1, ID: {d6fcdb52-f7c3-423b-b9f5-1e29f164c42e})
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 1"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: digitalOutput1, ID: {d6fcdb52-f7c3-423b-b9f5-1e29f164c42e})
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 1"),
|
||||
|
||||
//: The name of the StateType ({d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 1"),
|
||||
|
||||
//: The name of the EventType ({d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 1 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, ActionType: digitalOutput2, ID: {35de8b68-0cf3-4850-a27d-cf9c4a26921f})
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 2"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: digitalOutput2, ID: {35de8b68-0cf3-4850-a27d-cf9c4a26921f})
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 2"),
|
||||
|
||||
//: The name of the StateType ({35de8b68-0cf3-4850-a27d-cf9c4a26921f}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 2"),
|
||||
|
||||
//: The name of the EventType ({35de8b68-0cf3-4850-a27d-cf9c4a26921f}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital Output 2 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: digitalInput1, ID: {07165c12-4d53-45c0-8bf1-34618443b706})
|
||||
QT_TRANSLATE_NOOP("mock", "Digital input 1"),
|
||||
|
||||
//: The name of the StateType ({07165c12-4d53-45c0-8bf1-34618443b706}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital input 1"),
|
||||
|
||||
//: The name of the EventType ({07165c12-4d53-45c0-8bf1-34618443b706}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital input 1 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: genericIoMock, EventType: digitalInput2, ID: {0a4362ba-a086-4540-84ba-107ef7b99ed8})
|
||||
QT_TRANSLATE_NOOP("mock", "Digital input 2"),
|
||||
|
||||
//: The name of the StateType ({0a4362ba-a086-4540-84ba-107ef7b99ed8}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital input 2"),
|
||||
|
||||
//: The name of the EventType ({0a4362ba-a086-4540-84ba-107ef7b99ed8}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Digital input 2 changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: inputTypeMock, EventType: double, ID: {f7d2063d-959e-46ac-8568-8b99722d3b22})
|
||||
QT_TRANSLATE_NOOP("mock", "Double"),
|
||||
|
||||
@ -327,6 +463,15 @@ const QString translations[] {
|
||||
//: The name of the EventType ({80baec19-54de-4948-ac46-31eabfaceb83}) of ThingClass mock
|
||||
QT_TRANSLATE_NOOP("mock", "Dummy int state changed"),
|
||||
|
||||
//: The name of the ThingClass ({7cbd729a-465b-4ccb-b59c-5733039dbbed})
|
||||
QT_TRANSLATE_NOOP("mock", "Generic IO pins"),
|
||||
|
||||
//: The name of the ThingClass ({98ab137e-757e-43f8-9d9b-5d50d990242a})
|
||||
QT_TRANSLATE_NOOP("mock", "Generic Light (Mock)"),
|
||||
|
||||
//: The name of the ThingClass ({f8917e12-c9cb-4ea1-a06e-1ce6db2194f3})
|
||||
QT_TRANSLATE_NOOP("mock", "Generic Temperature Sensor (Mock)"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: inputTypeMock, Type: thing, ID: {9e5f86a0-4bb3-4892-bff8-3fc4032af6e2})
|
||||
QT_TRANSLATE_NOOP("mock", "IPv4 address"),
|
||||
|
||||
@ -348,6 +493,12 @@ const QString translations[] {
|
||||
//: The name of the ParamType (ThingClass: inputTypeMock, Type: thing, ID: {a8494faf-3a0f-4cf3-84b7-4b39148a838d})
|
||||
QT_TRANSLATE_NOOP("mock", "Mail address"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: virtualIoTemperatureSensorMock, Type: settings, ID: {7077c56f-c35b-4252-8c15-8fb549be04ce})
|
||||
QT_TRANSLATE_NOOP("mock", "Maximum temperature"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: virtualIoTemperatureSensorMock, Type: settings, ID: {803cddbf-94c7-4f35-bc7a-18698b03b942})
|
||||
QT_TRANSLATE_NOOP("mock", "Minimum temperature"),
|
||||
|
||||
//: The name of the ActionType ({07cd8d5f-2f65-4955-b1f9-05d7f4da488a}) of ThingClass autoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Mock Action 1 (with params)"),
|
||||
|
||||
@ -426,12 +577,36 @@ const QString translations[] {
|
||||
//: The name of the ParamType (ThingClass: inputTypeMock, Type: thing, ID: {e5c0d14b-c9f1-4aca-a56e-85bfa6977150})
|
||||
QT_TRANSLATE_NOOP("mock", "Password text"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: virtualIoLightMock, ActionType: power, ID: {d1917b3d-1530-4cf9-90f7-263ee88e714b})
|
||||
QT_TRANSLATE_NOOP("mock", "Power"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: virtualIoLightMock, EventType: power, ID: {d1917b3d-1530-4cf9-90f7-263ee88e714b})
|
||||
QT_TRANSLATE_NOOP("mock", "Power"),
|
||||
|
||||
//: The name of the StateType ({d1917b3d-1530-4cf9-90f7-263ee88e714b}) of ThingClass virtualIoLightMock
|
||||
QT_TRANSLATE_NOOP("mock", "Power"),
|
||||
|
||||
//: The name of the EventType ({d1917b3d-1530-4cf9-90f7-263ee88e714b}) of ThingClass virtualIoLightMock
|
||||
QT_TRANSLATE_NOOP("mock", "Power changed"),
|
||||
|
||||
//: The name of the Browser Item ActionType ({da6faef8-2816-430e-93bb-57e8f9582d29}) of ThingClass mock
|
||||
QT_TRANSLATE_NOOP("mock", "Remove from favorites"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: inputTypeMock, Type: thing, ID: {22add8c9-ee4f-43ad-8931-58e999313ac3})
|
||||
QT_TRANSLATE_NOOP("mock", "Search text"),
|
||||
|
||||
//: The name of the ActionType ({d6fcdb52-f7c3-423b-b9f5-1e29f164c42e}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set Digital Output 1"),
|
||||
|
||||
//: The name of the ActionType ({35de8b68-0cf3-4850-a27d-cf9c4a26921f}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set Digital Output 2"),
|
||||
|
||||
//: The name of the ActionType ({70cf053e-4abc-4d88-8e1e-2bd9a62256c7}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set Output Input 1"),
|
||||
|
||||
//: The name of the ActionType ({e40bcf7d-47b8-41fa-b213-3652a905b376}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set Output Input 2"),
|
||||
|
||||
//: The name of the ActionType ({a7c11774-f31f-4d64-99d1-e0ae5fb35a5c}) of ThingClass inputTypeMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set Writable Bool"),
|
||||
|
||||
@ -477,6 +652,9 @@ const QString translations[] {
|
||||
//: The name of the ActionType ({05f63f9c-f61e-4dcf-ad55-3f13fde2765b}) of ThingClass pushButtonMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set allowed values"),
|
||||
|
||||
//: The name of the ActionType ({ac56977c-cbba-47c6-a827-5735d8b0aed6}) of ThingClass genericIoMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set analog input 1"),
|
||||
|
||||
//: The name of the ActionType ({80ba1449-b485-47d4-a067-6bf306e2a568}) of ThingClass childMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set bool value"),
|
||||
|
||||
@ -507,6 +685,12 @@ const QString translations[] {
|
||||
//: The name of the ActionType ({72981c04-267a-4ba0-a59e-9921d2f3af9c}) of ThingClass pushButtonMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set percentage"),
|
||||
|
||||
//: The name of the ActionType ({d1917b3d-1530-4cf9-90f7-263ee88e714b}) of ThingClass virtualIoLightMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set power"),
|
||||
|
||||
//: The name of the ActionType ({db9cc518-1012-47e2-8212-6e616fed07a6}) of ThingClass virtualIoTemperatureSensorMock
|
||||
QT_TRANSLATE_NOOP("mock", "Set temperature"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: mock, Type: settings, ID: {367f7ba4-5039-47be-abd8-59cc8eaf4b9a})
|
||||
QT_TRANSLATE_NOOP("mock", "Setting 1"),
|
||||
|
||||
@ -519,6 +703,18 @@ const QString translations[] {
|
||||
//: The name of the EventType ({27f69ca9-a321-40ff-bfee-4b0272a671b4}) of ThingClass inputTypeMock
|
||||
QT_TRANSLATE_NOOP("mock", "String changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: virtualIoTemperatureSensorMock, ActionType: temperature, ID: {db9cc518-1012-47e2-8212-6e616fed07a6})
|
||||
QT_TRANSLATE_NOOP("mock", "Temperature"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: virtualIoTemperatureSensorMock, EventType: temperature, ID: {db9cc518-1012-47e2-8212-6e616fed07a6})
|
||||
QT_TRANSLATE_NOOP("mock", "Temperature"),
|
||||
|
||||
//: The name of the StateType ({db9cc518-1012-47e2-8212-6e616fed07a6}) of ThingClass virtualIoTemperatureSensorMock
|
||||
QT_TRANSLATE_NOOP("mock", "Temperature"),
|
||||
|
||||
//: The name of the EventType ({db9cc518-1012-47e2-8212-6e616fed07a6}) of ThingClass virtualIoTemperatureSensorMock
|
||||
QT_TRANSLATE_NOOP("mock", "Temperature changed"),
|
||||
|
||||
//: The name of the ParamType (ThingClass: inputTypeMock, Type: thing, ID: {716f0994-bc01-42b0-b64d-59236f7320d2})
|
||||
QT_TRANSLATE_NOOP("mock", "Text area"),
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
5.0
|
||||
5.1
|
||||
{
|
||||
"enums": {
|
||||
"BasicType": [
|
||||
@ -82,6 +82,13 @@
|
||||
"DeviceSetupStatusComplete",
|
||||
"DeviceSetupStatusFailed"
|
||||
],
|
||||
"IOType": [
|
||||
"IOTypeNone",
|
||||
"IOTypeDigitalInput",
|
||||
"IOTypeDigitalOutput",
|
||||
"IOTypeAnalogInput",
|
||||
"IOTypeAnalogOutput"
|
||||
],
|
||||
"InputType": [
|
||||
"InputTypeNone",
|
||||
"InputTypeTextLine",
|
||||
@ -937,6 +944,27 @@
|
||||
"thingError": "$ref:ThingError"
|
||||
}
|
||||
},
|
||||
"Integrations.ConnectIO": {
|
||||
"description": "Connect two generic IO states.",
|
||||
"params": {
|
||||
"inputStateTypeId": "Uuid",
|
||||
"inputThingId": "Uuid",
|
||||
"outputStateTypeId": "Uuid",
|
||||
"outputThingId": "Uuid"
|
||||
},
|
||||
"returns": {
|
||||
"thingError": "$ref:ThingError"
|
||||
}
|
||||
},
|
||||
"Integrations.DisconnectIO": {
|
||||
"description": "Disconnect an existing IO connection.",
|
||||
"params": {
|
||||
"ioConnectionId": "Uuid"
|
||||
},
|
||||
"returns": {
|
||||
"thingError": "$ref:ThingError"
|
||||
}
|
||||
},
|
||||
"Integrations.DiscoverThings": {
|
||||
"description": "Performs a thing discovery for things of the given thingClassId and returns the results. This function may take a while to return. Note that this method will include all the found things, that is, including things that may already have been added. Those things will have thingId set to the id of the already added thing. Such results may be used to reconfigure existing things and might be filtered in cases where only unknown things are of interest.",
|
||||
"params": {
|
||||
@ -1025,6 +1053,15 @@
|
||||
"eventTypes": "$ref:EventTypes"
|
||||
}
|
||||
},
|
||||
"Integrations.GetIOConnections": {
|
||||
"description": "Fetch IO connections. Optionally filtered by thingId and stateTypeId.",
|
||||
"params": {
|
||||
"o:thingId": "Uuid"
|
||||
},
|
||||
"returns": {
|
||||
"ioConnections": "$ref:IOConnections"
|
||||
}
|
||||
},
|
||||
"Integrations.GetPluginConfiguration": {
|
||||
"description": "Get a plugin's params.",
|
||||
"params": {
|
||||
@ -2015,6 +2052,18 @@
|
||||
"event": "$ref:Event"
|
||||
}
|
||||
},
|
||||
"Integrations.IOConnectionAdded": {
|
||||
"description": "Emitted whenever a IO connection is added.",
|
||||
"params": {
|
||||
"ioConnection": "$ref:IOConnection"
|
||||
}
|
||||
},
|
||||
"Integrations.IOConnectionRemoved": {
|
||||
"description": "Emitted whenever a IO connection is removed.",
|
||||
"params": {
|
||||
"ioConnectionId": "Uuid"
|
||||
}
|
||||
},
|
||||
"Integrations.PluginConfigurationChanged": {
|
||||
"description": "Emitted whenever a plugin's configuration is changed.",
|
||||
"params": {
|
||||
@ -2402,6 +2451,16 @@
|
||||
"name": "String",
|
||||
"version": "String"
|
||||
},
|
||||
"IOConnection": {
|
||||
"r:id": "Uuid",
|
||||
"r:inputStateTypeId": "Uuid",
|
||||
"r:inputThingId": "Uuid",
|
||||
"r:outputStateTypeId": "Uuid",
|
||||
"r:outputThingId": "Uuid"
|
||||
},
|
||||
"IOConnections": [
|
||||
"$ref:IOConnection"
|
||||
],
|
||||
"IntegrationPlugin": {
|
||||
"r:displayName": "String",
|
||||
"r:id": "Uuid",
|
||||
@ -2586,6 +2645,7 @@
|
||||
"displayName": "String",
|
||||
"index": "Int",
|
||||
"name": "String",
|
||||
"o:ioType": "$ref:IOType",
|
||||
"o:maxValue": "Variant",
|
||||
"o:minValue": "Variant",
|
||||
"o:possibleValues": [
|
||||
|
||||
@ -287,8 +287,8 @@ void TestIntegrations::getThingClasses_data()
|
||||
QTest::addColumn<VendorId>("vendorId");
|
||||
QTest::addColumn<int>("resultCount");
|
||||
|
||||
QTest::newRow("vendor nymea") << nymeaVendorId << 11;
|
||||
QTest::newRow("no filter") << VendorId() << 11;
|
||||
QTest::newRow("vendor nymea") << nymeaVendorId << 14;
|
||||
QTest::newRow("no filter") << VendorId() << 14;
|
||||
QTest::newRow("invalid vendor") << VendorId("93e7d361-8025-4354-b17e-b68406c800bc") << 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user