Add tests, some fixes/improvements
This commit is contained in:
parent
bee3904508
commit
4e509d75f8
@ -928,51 +928,61 @@ IOConnections ThingManagerImplementation::ioConnections(const ThingId &thingId)
|
|||||||
return ioConnections;
|
return ioConnections;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thing::ThingError ThingManagerImplementation::connectIO(const IOConnection &connection)
|
IOConnectionResult ThingManagerImplementation::connectIO(const IOConnection &connection)
|
||||||
{
|
{
|
||||||
|
IOConnectionResult result;
|
||||||
|
|
||||||
// Do some sanity checks
|
// Do some sanity checks
|
||||||
Thing *inputThing = m_configuredThings.value(connection.inputThingId());
|
Thing *inputThing = m_configuredThings.value(connection.inputThingId());
|
||||||
if (!inputThing) {
|
if (!inputThing) {
|
||||||
qCWarning(dcThingManager()) << "Could not find inputThing" << connection.inputThingId() << "configured things. Not adding IO connection.";
|
qCWarning(dcThingManager()) << "Could not find inputThing" << connection.inputThingId() << "in configured things. Not adding IO connection.";
|
||||||
return Thing::ThingErrorThingNotFound;
|
result.error = Thing::ThingErrorThingNotFound;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
if (!inputThing->thingClass().stateTypes().contains(connection.inputStateTypeId())) {
|
if (!inputThing->thingClass().stateTypes().contains(connection.inputStateTypeId())) {
|
||||||
qCWarning(dcThingManager()) << "Input thing" << inputThing->name() << "does not have a state with id" << connection.inputStateTypeId();
|
qCWarning(dcThingManager()) << "Input thing" << inputThing->name() << "does not have a state with id" << connection.inputStateTypeId();
|
||||||
return Thing::ThingErrorStateTypeNotFound;
|
result.error = Thing::ThingErrorStateTypeNotFound;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
StateType inputStateType = inputThing->thingClass().stateTypes().findById(connection.inputStateTypeId());
|
StateType inputStateType = inputThing->thingClass().stateTypes().findById(connection.inputStateTypeId());
|
||||||
|
|
||||||
// Check if this is actually an input
|
// Check if this is actually an input
|
||||||
if (inputStateType.ioType() != Types::IOTypeDigitalInput && inputStateType.ioType() != Types::IOTypeAnalogInput) {
|
if (inputStateType.ioType() != Types::IOTypeDigitalInput && inputStateType.ioType() != Types::IOTypeAnalogInput) {
|
||||||
qCWarning(dcThingManager()) << "The given input state is neither a digital nor an analog input.";
|
qCWarning(dcThingManager()) << "The given input state is neither a digital nor an analog input.";
|
||||||
return Thing::ThingErrorInvalidParameter;
|
result.error = Thing::ThingErrorInvalidParameter;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thing *outputThing = m_configuredThings.value(connection.outputThingId());
|
Thing *outputThing = m_configuredThings.value(connection.outputThingId());
|
||||||
if (!outputThing) {
|
if (!outputThing) {
|
||||||
qCWarning(dcThingManager()) << "Could not find outputThing" << connection.outputThingId() << "configured things. Not adding IO connection.";
|
qCWarning(dcThingManager()) << "Could not find outputThing" << connection.outputThingId() << "in configured things. Not adding IO connection.";
|
||||||
return Thing::ThingErrorThingNotFound;
|
result.error = Thing::ThingErrorThingNotFound;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
if (!outputThing->thingClass().stateTypes().contains(connection.outputStateTypeId())) {
|
if (!outputThing->thingClass().stateTypes().contains(connection.outputStateTypeId())) {
|
||||||
qCWarning(dcThingManager()) << "Output thing" << outputThing->name() << "does not have a state with id" << connection.outputStateTypeId();
|
qCWarning(dcThingManager()) << "Output thing" << outputThing->name() << "does not have a state with id" << connection.outputStateTypeId();
|
||||||
return Thing::ThingErrorStateTypeNotFound;
|
result.error = Thing::ThingErrorStateTypeNotFound;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
StateType outputStateType = outputThing->thingClass().stateTypes().findById(connection.outputStateTypeId());
|
StateType outputStateType = outputThing->thingClass().stateTypes().findById(connection.outputStateTypeId());
|
||||||
|
|
||||||
// Check if this is actually an output
|
// Check if this is actually an output
|
||||||
if (outputStateType.ioType() != Types::IOTypeDigitalOutput && outputStateType.ioType() != Types::IOTypeAnalogOutput) {
|
if (outputStateType.ioType() != Types::IOTypeDigitalOutput && outputStateType.ioType() != Types::IOTypeAnalogOutput) {
|
||||||
qCWarning(dcThingManager()) << "The given output state is neither a digital nor an analog output.";
|
qCWarning(dcThingManager()) << "The given output state is neither a digital nor an analog output.";
|
||||||
return Thing::ThingErrorInvalidParameter;
|
result.error = Thing::ThingErrorInvalidParameter;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if io types are compatible
|
// Check if io types are compatible
|
||||||
if (inputStateType.ioType() == Types::IOTypeDigitalInput && outputStateType.ioType() != Types::IOTypeDigitalOutput) {
|
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();
|
qCWarning(dcThingManager()) << "Cannot connect IOs of different type:" << inputStateType.ioType() << "is not compatible with" << outputStateType.ioType();
|
||||||
return Thing::ThingErrorInvalidParameter;
|
result.error = Thing::ThingErrorInvalidParameter;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
if (inputStateType.ioType() == Types::IOTypeAnalogInput && outputStateType.ioType() != Types::IOTypeAnalogOutput) {
|
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();
|
qCWarning(dcThingManager()) << "Cannot connect IOs of different type:" << inputStateType.ioType() << "is not compatible with" << outputStateType.ioType();
|
||||||
return Thing::ThingErrorInvalidParameter;
|
result.error = Thing::ThingErrorInvalidParameter;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if either input or output is already connected
|
// Check if either input or output is already connected
|
||||||
@ -994,7 +1004,10 @@ Thing::ThingError ThingManagerImplementation::connectIO(const IOConnection &conn
|
|||||||
storeIOConnections();
|
storeIOConnections();
|
||||||
|
|
||||||
emit ioConnectionAdded(connection);
|
emit ioConnectionAdded(connection);
|
||||||
return Thing::ThingErrorNoError;
|
|
||||||
|
result.error = Thing::ThingErrorNoError;
|
||||||
|
result.ioConnectionId = connection.id();
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Thing::ThingError ThingManagerImplementation::disconnectIO(const IOConnectionId &ioConnectionId)
|
Thing::ThingError ThingManagerImplementation::disconnectIO(const IOConnectionId &ioConnectionId)
|
||||||
|
|||||||
@ -115,7 +115,7 @@ public:
|
|||||||
BrowserItemActionInfo *executeBrowserItemAction(const BrowserItemAction &browserItemAction) override;
|
BrowserItemActionInfo *executeBrowserItemAction(const BrowserItemAction &browserItemAction) override;
|
||||||
|
|
||||||
IOConnections ioConnections(const ThingId &thingId = ThingId()) const override;
|
IOConnections ioConnections(const ThingId &thingId = ThingId()) const override;
|
||||||
Thing::ThingError connectIO(const IOConnection &connection) override;
|
IOConnectionResult connectIO(const IOConnection &connection) override;
|
||||||
Thing::ThingError disconnectIO(const IOConnectionId &ioConnectionId) override;
|
Thing::ThingError disconnectIO(const IOConnectionId &ioConnectionId) override;
|
||||||
|
|
||||||
QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) override;
|
QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) override;
|
||||||
|
|||||||
@ -355,12 +355,14 @@ IntegrationsHandler::IntegrationsHandler(ThingManager *thingManager, QObject *pa
|
|||||||
registerMethod("GetIOConnections", description, params, returns);
|
registerMethod("GetIOConnections", description, params, returns);
|
||||||
|
|
||||||
params.clear(); returns.clear();
|
params.clear(); returns.clear();
|
||||||
description = "Connect two generic IO states.";
|
description = "Connect two generic IO states. Input and output need to be compatible, that is, either a digital input "
|
||||||
|
"and a digital output, or an analog input and an analog output. If successful, the connectionId will be returned.";
|
||||||
params.insert("inputThingId", enumValueName(Uuid));
|
params.insert("inputThingId", enumValueName(Uuid));
|
||||||
params.insert("inputStateTypeId", enumValueName(Uuid));
|
params.insert("inputStateTypeId", enumValueName(Uuid));
|
||||||
params.insert("outputThingId", enumValueName(Uuid));
|
params.insert("outputThingId", enumValueName(Uuid));
|
||||||
params.insert("outputStateTypeId", enumValueName(Uuid));
|
params.insert("outputStateTypeId", enumValueName(Uuid));
|
||||||
returns.insert("thingError", enumRef<Thing::ThingError>());
|
returns.insert("thingError", enumRef<Thing::ThingError>());
|
||||||
|
returns.insert("o:ioConnectionId", enumValueName(Uuid));
|
||||||
registerMethod("ConnectIO", description, params, returns);
|
registerMethod("ConnectIO", description, params, returns);
|
||||||
|
|
||||||
params.clear(); returns.clear();
|
params.clear(); returns.clear();
|
||||||
@ -990,8 +992,12 @@ JsonReply *IntegrationsHandler::ConnectIO(const QVariantMap ¶ms)
|
|||||||
StateTypeId inputStateTypeId = params.value("inputStateTypeId").toUuid();
|
StateTypeId inputStateTypeId = params.value("inputStateTypeId").toUuid();
|
||||||
ThingId outputThingId = params.value("outputThingId").toUuid();
|
ThingId outputThingId = params.value("outputThingId").toUuid();
|
||||||
StateTypeId outputStateTypeId = params.value("outputStateTypeId").toUuid();
|
StateTypeId outputStateTypeId = params.value("outputStateTypeId").toUuid();
|
||||||
Thing::ThingError error = m_thingManager->connectIO(inputThingId, inputStateTypeId, outputThingId, outputStateTypeId);
|
IOConnectionResult result = m_thingManager->connectIO(inputThingId, inputStateTypeId, outputThingId, outputStateTypeId);
|
||||||
return createReply(statusToReply(error));
|
QVariantMap reply = statusToReply(result.error);
|
||||||
|
if (result.error == Thing::ThingErrorNoError) {
|
||||||
|
reply.insert("ioConnectionId", result.ioConnectionId);
|
||||||
|
}
|
||||||
|
return createReply(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonReply *IntegrationsHandler::DisconnectIO(const QVariantMap ¶ms)
|
JsonReply *IntegrationsHandler::DisconnectIO(const QVariantMap ¶ms)
|
||||||
|
|||||||
@ -6,6 +6,12 @@
|
|||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
#include "typeutils.h"
|
#include "typeutils.h"
|
||||||
|
#include "thing.h"
|
||||||
|
|
||||||
|
struct IOConnectionResult {
|
||||||
|
Thing::ThingError error = Thing::ThingErrorNoError;
|
||||||
|
IOConnectionId ioConnectionId;
|
||||||
|
};
|
||||||
|
|
||||||
class IOConnection
|
class IOConnection
|
||||||
{
|
{
|
||||||
|
|||||||
@ -51,7 +51,7 @@ ThingManager::ThingManager(QObject *parent) : QObject(parent)
|
|||||||
qRegisterMetaType<ParamTypes>();
|
qRegisterMetaType<ParamTypes>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thing::ThingError ThingManager::connectIO(const ThingId &inputThing, const StateTypeId &inputState, const ThingId &outputThing, const StateTypeId &outputState)
|
IOConnectionResult ThingManager::connectIO(const ThingId &inputThing, const StateTypeId &inputState, const ThingId &outputThing, const StateTypeId &outputState)
|
||||||
{
|
{
|
||||||
IOConnection connection(IOConnectionId::createIOConnectionId(), inputThing, inputState, outputThing, outputState);
|
IOConnection connection(IOConnectionId::createIOConnectionId(), inputThing, inputState, outputThing, outputState);
|
||||||
return connectIO(connection);
|
return connectIO(connection);
|
||||||
|
|||||||
@ -91,7 +91,7 @@ public:
|
|||||||
virtual BrowserItemActionInfo* executeBrowserItemAction(const BrowserItemAction &browserItemAction) = 0;
|
virtual BrowserItemActionInfo* executeBrowserItemAction(const BrowserItemAction &browserItemAction) = 0;
|
||||||
|
|
||||||
virtual IOConnections ioConnections(const ThingId &thingId = ThingId()) const = 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);
|
IOConnectionResult connectIO(const ThingId &inputThing, const StateTypeId &inputState, const ThingId &outputThing, const StateTypeId &outputState);
|
||||||
virtual Thing::ThingError disconnectIO(const IOConnectionId &ioConnectionId) = 0;
|
virtual Thing::ThingError disconnectIO(const IOConnectionId &ioConnectionId) = 0;
|
||||||
|
|
||||||
virtual QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) = 0;
|
virtual QString translate(const PluginId &pluginId, const QString &string, const QLocale &locale) = 0;
|
||||||
@ -100,7 +100,7 @@ public:
|
|||||||
virtual Vendor translateVendor(const Vendor &vendor, const QLocale &locale) = 0;
|
virtual Vendor translateVendor(const Vendor &vendor, const QLocale &locale) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Thing::ThingError connectIO(const IOConnection &connection) = 0;
|
virtual IOConnectionResult connectIO(const IOConnection &connection) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void pluginConfigChanged(const PluginId &id, const ParamList &config);
|
void pluginConfigChanged(const PluginId &id, const ParamList &config);
|
||||||
|
|||||||
@ -290,10 +290,13 @@ extern ParamTypeId virtualIoLightMockPowerActionPowerParamTypeId;
|
|||||||
extern ThingClassId virtualIoTemperatureSensorMockThingClassId;
|
extern ThingClassId virtualIoTemperatureSensorMockThingClassId;
|
||||||
extern ParamTypeId virtualIoTemperatureSensorMockSettingsMinTempParamTypeId;
|
extern ParamTypeId virtualIoTemperatureSensorMockSettingsMinTempParamTypeId;
|
||||||
extern ParamTypeId virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId;
|
extern ParamTypeId virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId;
|
||||||
|
extern StateTypeId virtualIoTemperatureSensorMockInputStateTypeId;
|
||||||
extern StateTypeId virtualIoTemperatureSensorMockTemperatureStateTypeId;
|
extern StateTypeId virtualIoTemperatureSensorMockTemperatureStateTypeId;
|
||||||
|
extern EventTypeId virtualIoTemperatureSensorMockInputEventTypeId;
|
||||||
|
extern ParamTypeId virtualIoTemperatureSensorMockInputEventInputParamTypeId;
|
||||||
extern EventTypeId virtualIoTemperatureSensorMockTemperatureEventTypeId;
|
extern EventTypeId virtualIoTemperatureSensorMockTemperatureEventTypeId;
|
||||||
extern ParamTypeId virtualIoTemperatureSensorMockTemperatureEventTemperatureParamTypeId;
|
extern ParamTypeId virtualIoTemperatureSensorMockTemperatureEventTemperatureParamTypeId;
|
||||||
extern ActionTypeId virtualIoTemperatureSensorMockTemperatureActionTypeId;
|
extern ActionTypeId virtualIoTemperatureSensorMockInputActionTypeId;
|
||||||
extern ParamTypeId virtualIoTemperatureSensorMockTemperatureActionTemperatureParamTypeId;
|
extern ParamTypeId virtualIoTemperatureSensorMockInputActionInputParamTypeId;
|
||||||
|
|
||||||
#endif // EXTERNPLUGININFO_H
|
#endif // EXTERNPLUGININFO_H
|
||||||
|
|||||||
@ -748,11 +748,12 @@ void IntegrationPluginMock::executeAction(ThingActionInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (info->thing()->thingClassId() == virtualIoTemperatureSensorMockThingClassId) {
|
if (info->thing()->thingClassId() == virtualIoTemperatureSensorMockThingClassId) {
|
||||||
if (info->action().actionTypeId() == virtualIoTemperatureSensorMockTemperatureActionTypeId) {
|
if (info->action().actionTypeId() == virtualIoTemperatureSensorMockInputActionTypeId) {
|
||||||
double minTemp = info->thing()->setting(virtualIoTemperatureSensorMockSettingsMinTempParamTypeId).toDouble();
|
double minTemp = info->thing()->setting(virtualIoTemperatureSensorMockSettingsMinTempParamTypeId).toDouble();
|
||||||
double maxTemp = info->thing()->setting(virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId).toDouble();
|
double maxTemp = info->thing()->setting(virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId).toDouble();
|
||||||
double value = info->action().param(virtualIoTemperatureSensorMockTemperatureActionTemperatureParamTypeId).value().toDouble();
|
double value = info->action().param(virtualIoTemperatureSensorMockInputActionInputParamTypeId).value().toDouble();
|
||||||
double temp = minTemp + (maxTemp - minTemp) * value;
|
double temp = minTemp + (maxTemp - minTemp) * value;
|
||||||
|
qCDebug(dcMock()) << "Min:" << minTemp << "Max:" << maxTemp << "value:" << value << "temp:" << temp;
|
||||||
info->thing()->setStateValue(virtualIoTemperatureSensorMockTemperatureStateTypeId, temp);
|
info->thing()->setStateValue(virtualIoTemperatureSensorMockTemperatureStateTypeId, temp);
|
||||||
info->finish(Thing::ThingErrorNoError);
|
info->finish(Thing::ThingErrorNoError);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -1016,18 +1016,26 @@
|
|||||||
],
|
],
|
||||||
"stateTypes": [
|
"stateTypes": [
|
||||||
{
|
{
|
||||||
"id": "db9cc518-1012-47e2-8212-6e616fed07a6",
|
"id": "fd341f72-6d9a-4812-9f66-47197c48a935",
|
||||||
"name": "temperature",
|
"name": "input",
|
||||||
"displayName": "Temperature",
|
"displayName": "Input",
|
||||||
"displayNameEvent": "Temperature changed",
|
"displayNameEvent": "Input changed",
|
||||||
"displayNameAction": "Set temperature",
|
"displayNameAction": "Set input",
|
||||||
"type": "double",
|
"type": "double",
|
||||||
"unit": "DegreeCelsius",
|
|
||||||
"defaultValue": 0,
|
"defaultValue": 0,
|
||||||
"ioType": "analogOutput",
|
"ioType": "analogOutput",
|
||||||
"writable": true,
|
"writable": true,
|
||||||
"minValue": 0,
|
"minValue": 0,
|
||||||
"maxValue": 1
|
"maxValue": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "db9cc518-1012-47e2-8212-6e616fed07a6",
|
||||||
|
"name": "temperature",
|
||||||
|
"displayName": "Temperature",
|
||||||
|
"displayNameEvent": "Temperature changed",
|
||||||
|
"type": "double",
|
||||||
|
"unit": "DegreeCelsius",
|
||||||
|
"defaultValue": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -294,11 +294,14 @@ ParamTypeId virtualIoLightMockPowerActionPowerParamTypeId = ParamTypeId("{d1917b
|
|||||||
ThingClassId virtualIoTemperatureSensorMockThingClassId = ThingClassId("{f8917e12-c9cb-4ea1-a06e-1ce6db2194f3}");
|
ThingClassId virtualIoTemperatureSensorMockThingClassId = ThingClassId("{f8917e12-c9cb-4ea1-a06e-1ce6db2194f3}");
|
||||||
ParamTypeId virtualIoTemperatureSensorMockSettingsMinTempParamTypeId = ParamTypeId("{803cddbf-94c7-4f35-bc7a-18698b03b942}");
|
ParamTypeId virtualIoTemperatureSensorMockSettingsMinTempParamTypeId = ParamTypeId("{803cddbf-94c7-4f35-bc7a-18698b03b942}");
|
||||||
ParamTypeId virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId = ParamTypeId("{7077c56f-c35b-4252-8c15-8fb549be04ce}");
|
ParamTypeId virtualIoTemperatureSensorMockSettingsMaxTempParamTypeId = ParamTypeId("{7077c56f-c35b-4252-8c15-8fb549be04ce}");
|
||||||
|
StateTypeId virtualIoTemperatureSensorMockInputStateTypeId = StateTypeId("{fd341f72-6d9a-4812-9f66-47197c48a935}");
|
||||||
StateTypeId virtualIoTemperatureSensorMockTemperatureStateTypeId = StateTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
StateTypeId virtualIoTemperatureSensorMockTemperatureStateTypeId = StateTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||||
|
EventTypeId virtualIoTemperatureSensorMockInputEventTypeId = EventTypeId("{fd341f72-6d9a-4812-9f66-47197c48a935}");
|
||||||
|
ParamTypeId virtualIoTemperatureSensorMockInputEventInputParamTypeId = ParamTypeId("{fd341f72-6d9a-4812-9f66-47197c48a935}");
|
||||||
EventTypeId virtualIoTemperatureSensorMockTemperatureEventTypeId = EventTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
EventTypeId virtualIoTemperatureSensorMockTemperatureEventTypeId = EventTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||||
ParamTypeId virtualIoTemperatureSensorMockTemperatureEventTemperatureParamTypeId = ParamTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
ParamTypeId virtualIoTemperatureSensorMockTemperatureEventTemperatureParamTypeId = ParamTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
||||||
ActionTypeId virtualIoTemperatureSensorMockTemperatureActionTypeId = ActionTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
ActionTypeId virtualIoTemperatureSensorMockInputActionTypeId = ActionTypeId("{fd341f72-6d9a-4812-9f66-47197c48a935}");
|
||||||
ParamTypeId virtualIoTemperatureSensorMockTemperatureActionTemperatureParamTypeId = ParamTypeId("{db9cc518-1012-47e2-8212-6e616fed07a6}");
|
ParamTypeId virtualIoTemperatureSensorMockInputActionInputParamTypeId = ParamTypeId("{fd341f72-6d9a-4812-9f66-47197c48a935}");
|
||||||
|
|
||||||
const QString translations[] {
|
const QString translations[] {
|
||||||
//: The name of the Browser Item ActionType ({00b8f0a8-99ca-4aa4-833d-59eb8d4d6de3}) of ThingClass mock
|
//: The name of the Browser Item ActionType ({00b8f0a8-99ca-4aa4-833d-59eb8d4d6de3}) of ThingClass mock
|
||||||
@ -478,6 +481,18 @@ const QString translations[] {
|
|||||||
//: The name of the ParamType (ThingClass: inputTypeMock, Type: thing, ID: {43bf3832-dd48-4090-a836-656e8b60216e})
|
//: The name of the ParamType (ThingClass: inputTypeMock, Type: thing, ID: {43bf3832-dd48-4090-a836-656e8b60216e})
|
||||||
QT_TRANSLATE_NOOP("mock", "IPv6 address"),
|
QT_TRANSLATE_NOOP("mock", "IPv6 address"),
|
||||||
|
|
||||||
|
//: The name of the ParamType (ThingClass: virtualIoTemperatureSensorMock, ActionType: input, ID: {fd341f72-6d9a-4812-9f66-47197c48a935})
|
||||||
|
QT_TRANSLATE_NOOP("mock", "Input"),
|
||||||
|
|
||||||
|
//: The name of the ParamType (ThingClass: virtualIoTemperatureSensorMock, EventType: input, ID: {fd341f72-6d9a-4812-9f66-47197c48a935})
|
||||||
|
QT_TRANSLATE_NOOP("mock", "Input"),
|
||||||
|
|
||||||
|
//: The name of the StateType ({fd341f72-6d9a-4812-9f66-47197c48a935}) of ThingClass virtualIoTemperatureSensorMock
|
||||||
|
QT_TRANSLATE_NOOP("mock", "Input"),
|
||||||
|
|
||||||
|
//: The name of the EventType ({fd341f72-6d9a-4812-9f66-47197c48a935}) of ThingClass virtualIoTemperatureSensorMock
|
||||||
|
QT_TRANSLATE_NOOP("mock", "Input changed"),
|
||||||
|
|
||||||
//: The name of the ParamType (ThingClass: inputTypeMock, EventType: int, ID: {d0fc56ae-5791-4e91-b76c-dadfbc7e7dbb})
|
//: The name of the ParamType (ThingClass: inputTypeMock, EventType: int, ID: {d0fc56ae-5791-4e91-b76c-dadfbc7e7dbb})
|
||||||
QT_TRANSLATE_NOOP("mock", "Int"),
|
QT_TRANSLATE_NOOP("mock", "Int"),
|
||||||
|
|
||||||
@ -679,6 +694,9 @@ const QString translations[] {
|
|||||||
//: The name of the ActionType ({53cd7c55-49b7-441b-b970-9048f20f0e2c}) of ThingClass pushButtonMock
|
//: The name of the ActionType ({53cd7c55-49b7-441b-b970-9048f20f0e2c}) of ThingClass pushButtonMock
|
||||||
QT_TRANSLATE_NOOP("mock", "Set double value"),
|
QT_TRANSLATE_NOOP("mock", "Set double value"),
|
||||||
|
|
||||||
|
//: The name of the ActionType ({fd341f72-6d9a-4812-9f66-47197c48a935}) of ThingClass virtualIoTemperatureSensorMock
|
||||||
|
QT_TRANSLATE_NOOP("mock", "Set input"),
|
||||||
|
|
||||||
//: The name of the ActionType ({527f0687-0b28-4c26-852c-25b8f83e4797}) of ThingClass displayPinMock
|
//: The name of the ActionType ({527f0687-0b28-4c26-852c-25b8f83e4797}) of ThingClass displayPinMock
|
||||||
QT_TRANSLATE_NOOP("mock", "Set percentage"),
|
QT_TRANSLATE_NOOP("mock", "Set percentage"),
|
||||||
|
|
||||||
@ -688,9 +706,6 @@ const QString translations[] {
|
|||||||
//: The name of the ActionType ({d1917b3d-1530-4cf9-90f7-263ee88e714b}) of ThingClass virtualIoLightMock
|
//: The name of the ActionType ({d1917b3d-1530-4cf9-90f7-263ee88e714b}) of ThingClass virtualIoLightMock
|
||||||
QT_TRANSLATE_NOOP("mock", "Set power"),
|
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})
|
//: The name of the ParamType (ThingClass: mock, Type: settings, ID: {367f7ba4-5039-47be-abd8-59cc8eaf4b9a})
|
||||||
QT_TRANSLATE_NOOP("mock", "Setting 1"),
|
QT_TRANSLATE_NOOP("mock", "Setting 1"),
|
||||||
|
|
||||||
@ -703,9 +718,6 @@ const QString translations[] {
|
|||||||
//: The name of the EventType ({27f69ca9-a321-40ff-bfee-4b0272a671b4}) of ThingClass inputTypeMock
|
//: The name of the EventType ({27f69ca9-a321-40ff-bfee-4b0272a671b4}) of ThingClass inputTypeMock
|
||||||
QT_TRANSLATE_NOOP("mock", "String changed"),
|
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})
|
//: The name of the ParamType (ThingClass: virtualIoTemperatureSensorMock, EventType: temperature, ID: {db9cc518-1012-47e2-8212-6e616fed07a6})
|
||||||
QT_TRANSLATE_NOOP("mock", "Temperature"),
|
QT_TRANSLATE_NOOP("mock", "Temperature"),
|
||||||
|
|
||||||
|
|||||||
@ -945,7 +945,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Integrations.ConnectIO": {
|
"Integrations.ConnectIO": {
|
||||||
"description": "Connect two generic IO states.",
|
"description": "Connect two generic IO states. Input and output need to be compatible, that is, either a digital input and a digital output, or an analog input and an analog output. If successful, the connectionId will be returned.",
|
||||||
"params": {
|
"params": {
|
||||||
"inputStateTypeId": "Uuid",
|
"inputStateTypeId": "Uuid",
|
||||||
"inputThingId": "Uuid",
|
"inputThingId": "Uuid",
|
||||||
@ -953,6 +953,7 @@
|
|||||||
"outputThingId": "Uuid"
|
"outputThingId": "Uuid"
|
||||||
},
|
},
|
||||||
"returns": {
|
"returns": {
|
||||||
|
"o:ioConnectionId": "Uuid",
|
||||||
"thingError": "$ref:ThingError"
|
"thingError": "$ref:ThingError"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,26 +1,27 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
versioning \
|
|
||||||
devices \
|
|
||||||
integrations \
|
|
||||||
jsonrpc \
|
|
||||||
events \
|
|
||||||
states \
|
|
||||||
actions \
|
actions \
|
||||||
rules \
|
configurations \
|
||||||
plugins \
|
devices \
|
||||||
webserver \
|
events \
|
||||||
websocketserver \
|
integrations \
|
||||||
|
ioconnections \
|
||||||
|
jsonrpc \
|
||||||
logging \
|
logging \
|
||||||
loggingdirect \
|
loggingdirect \
|
||||||
loggingloading \
|
loggingloading \
|
||||||
#coap \ # temporary removed until fixed
|
mqttbroker \
|
||||||
configurations \
|
plugins \
|
||||||
|
rules \
|
||||||
|
scripts \
|
||||||
|
states \
|
||||||
|
tags \
|
||||||
timemanager \
|
timemanager \
|
||||||
userloading \
|
userloading \
|
||||||
usermanager \
|
usermanager \
|
||||||
mqttbroker \
|
versioning \
|
||||||
tags \
|
webserver \
|
||||||
scripts \
|
websocketserver \
|
||||||
|
#coap \ # temporary removed until fixed
|
||||||
|
|
||||||
|
|||||||
5
tests/auto/ioconnections/ioconnections.pro
Normal file
5
tests/auto/ioconnections/ioconnections.pro
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
include(../../../nymea.pri)
|
||||||
|
include(../autotests.pri)
|
||||||
|
|
||||||
|
TARGET = testioconnections
|
||||||
|
SOURCES += testioconnections.cpp
|
||||||
299
tests/auto/ioconnections/testioconnections.cpp
Normal file
299
tests/auto/ioconnections/testioconnections.cpp
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Copyright 2013 - 2020, nymea GmbH
|
||||||
|
* Contact: contact@nymea.io
|
||||||
|
*
|
||||||
|
* This file is part of nymea.
|
||||||
|
* This project including source code and documentation is protected by
|
||||||
|
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||||
|
* reproduction, publication, editing and translation, are reserved. The use of
|
||||||
|
* this project is subject to the terms of a license agreement to be concluded
|
||||||
|
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||||
|
* under https://nymea.io/license
|
||||||
|
*
|
||||||
|
* GNU General Public License Usage
|
||||||
|
* Alternatively, this project may be redistributed and/or modified under the
|
||||||
|
* terms of the GNU General Public License as published by the Free Software
|
||||||
|
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||||
|
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* For any further details and any questions please contact us under
|
||||||
|
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||||
|
* https://nymea.io/license/faq
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "nymeatestbase.h"
|
||||||
|
#include "nymeacore.h"
|
||||||
|
#include "nymeasettings.h"
|
||||||
|
|
||||||
|
#include "integrations/thingdiscoveryinfo.h"
|
||||||
|
#include "integrations/thingsetupinfo.h"
|
||||||
|
|
||||||
|
#include "servers/mocktcpserver.h"
|
||||||
|
#include "jsonrpc/integrationshandler.h"
|
||||||
|
|
||||||
|
using namespace nymeaserver;
|
||||||
|
|
||||||
|
class TestIOConnections : public NymeaTestBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
ThingId m_ioThingId;
|
||||||
|
ThingId m_lightThingId;
|
||||||
|
ThingId m_tempSensorThingId;
|
||||||
|
|
||||||
|
inline void verifyThingError(const QVariant &response, Thing::ThingError error = Thing::ThingErrorNoError) {
|
||||||
|
verifyError(response, "thingError", enumValueName(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void initTestCase();
|
||||||
|
|
||||||
|
void testConnectionCompatibility_data();
|
||||||
|
void testConnectionCompatibility();
|
||||||
|
|
||||||
|
void testDigitalIO();
|
||||||
|
|
||||||
|
void testAnalogIO();
|
||||||
|
};
|
||||||
|
|
||||||
|
void TestIOConnections::initTestCase()
|
||||||
|
{
|
||||||
|
NymeaTestBase::initTestCase();
|
||||||
|
QLoggingCategory::setFilterRules("*.debug=false\n"
|
||||||
|
"Tests.debug=true\n"
|
||||||
|
"Mock.debug=true\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Adding generic IO mock
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("thingClassId", genericIoMockThingClassId);
|
||||||
|
params.insert("name", "Generic IO mock");
|
||||||
|
QVariant response = injectAndWait("Integrations.AddThing", params);
|
||||||
|
m_ioThingId = ThingId(response.toMap().value("params").toMap().value("thingId").toString());
|
||||||
|
QVERIFY2(!m_ioThingId.isNull(), "Creating generic IO mock failed");
|
||||||
|
qCDebug(dcTests()) << "Created IO mock with ID" << m_ioThingId;
|
||||||
|
|
||||||
|
// Adding virtual light (digital input)
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingClassId", virtualIoLightMockThingClassId);
|
||||||
|
params.insert("name", "light");
|
||||||
|
response = injectAndWait("Integrations.AddThing", params);
|
||||||
|
m_lightThingId = ThingId(response.toMap().value("params").toMap().value("thingId").toUuid());
|
||||||
|
QVERIFY2(!m_lightThingId.isNull(), "Creating virtual light failed");
|
||||||
|
|
||||||
|
// Adding virtual temp sensor (analog output)
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingClassId", virtualIoTemperatureSensorMockThingClassId);
|
||||||
|
params.insert("name", "temp sensor");
|
||||||
|
response = injectAndWait("Integrations.AddThing", params);
|
||||||
|
m_tempSensorThingId = ThingId(response.toMap().value("params").toMap().value("thingId").toUuid());
|
||||||
|
QVERIFY2(!m_tempSensorThingId.isNull(), "Creating virtual temp sensor failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestIOConnections::testConnectionCompatibility_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<ThingId>("inputThingId");
|
||||||
|
QTest::addColumn<StateTypeId>("inputStateTypeId");
|
||||||
|
QTest::addColumn<ThingId>("outputThingId");
|
||||||
|
QTest::addColumn<StateTypeId>("outputStateTypeId");
|
||||||
|
QTest::addColumn<Thing::ThingError>("expectedError");
|
||||||
|
|
||||||
|
QTest::newRow("digital in, digital in") << m_ioThingId << genericIoMockDigitalInput1StateTypeId << m_ioThingId << genericIoMockDigitalInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("digital in, digital out") << m_ioThingId << genericIoMockDigitalInput1StateTypeId << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << Thing::ThingErrorNoError;
|
||||||
|
QTest::newRow("digital in, analog in") << m_ioThingId << genericIoMockDigitalInput1StateTypeId << m_ioThingId << genericIoMockAnalogInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("digital in, analog out") << m_ioThingId << genericIoMockDigitalInput1StateTypeId << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
|
||||||
|
QTest::newRow("digital out, digital in") << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << m_ioThingId << genericIoMockDigitalInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("digital out, digital out") << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("digital out, analog in") << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << m_ioThingId << genericIoMockAnalogInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("digital out, analot out") << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
|
||||||
|
QTest::newRow("analog in, digital in") << m_ioThingId << genericIoMockAnalogInput1StateTypeId << m_ioThingId << genericIoMockDigitalInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("analog in, digital out") << m_ioThingId << genericIoMockAnalogInput1StateTypeId << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("analog in, analog in") << m_ioThingId << genericIoMockAnalogInput1StateTypeId << m_ioThingId << genericIoMockAnalogInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("analog in, analog out") << m_ioThingId << genericIoMockAnalogInput1StateTypeId << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << Thing::ThingErrorNoError;
|
||||||
|
|
||||||
|
QTest::newRow("analog out, digital in") << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << m_ioThingId << genericIoMockDigitalInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("analog out, digital out") << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("analog out, analog in") << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << m_ioThingId << genericIoMockAnalogInput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
QTest::newRow("analog out, analog out") << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << m_ioThingId << genericIoMockAnalogOutput1StateTypeId << Thing::ThingErrorInvalidParameter;
|
||||||
|
|
||||||
|
QTest::newRow("valid input, invalid output thing") << m_ioThingId << genericIoMockDigitalInput1StateTypeId << ThingId("707d5093-4915-499e-8e69-10c11972bb34") << genericIoMockDigitalOutput1StateTypeId << Thing::ThingErrorThingNotFound;
|
||||||
|
QTest::newRow("valid input, invalid output stateType") << m_ioThingId << genericIoMockDigitalInput1StateTypeId << m_ioThingId << StateTypeId("51534cd7-8adf-4bdc-a4c1-042d0a9d4faa") << Thing::ThingErrorStateTypeNotFound;
|
||||||
|
QTest::newRow("invalid input thing, valid output") << ThingId("99843693-8615-416a-8e59-a47b050f5c1a") << genericIoMockDigitalInput1StateTypeId << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << Thing::ThingErrorThingNotFound;
|
||||||
|
QTest::newRow("invalid input stateType, valid output") << m_ioThingId << StateTypeId("04657948-e349-4f43-bf20-13f9986ad1b4") << m_ioThingId << genericIoMockDigitalOutput1StateTypeId << Thing::ThingErrorStateTypeNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestIOConnections::testConnectionCompatibility()
|
||||||
|
{
|
||||||
|
QFETCH(ThingId, inputThingId);
|
||||||
|
QFETCH(StateTypeId, inputStateTypeId);
|
||||||
|
QFETCH(ThingId, outputThingId);
|
||||||
|
QFETCH(StateTypeId, outputStateTypeId);
|
||||||
|
QFETCH(Thing::ThingError, expectedError);
|
||||||
|
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("inputThingId", inputThingId);
|
||||||
|
params.insert("inputStateTypeId", inputStateTypeId);
|
||||||
|
params.insert("outputThingId", outputThingId);
|
||||||
|
params.insert("outputStateTypeId", outputStateTypeId);
|
||||||
|
QVariant response = injectAndWait("Integrations.ConnectIO", params);
|
||||||
|
verifyThingError(response, expectedError);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestIOConnections::testDigitalIO()
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("inputThingId", m_lightThingId);
|
||||||
|
params.insert("inputStateTypeId", virtualIoLightMockPowerStateTypeId);
|
||||||
|
params.insert("outputThingId", m_ioThingId);
|
||||||
|
params.insert("outputStateTypeId", genericIoMockDigitalOutput1StateTypeId);
|
||||||
|
QVariant response = injectAndWait("Integrations.ConnectIO", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
IOConnectionId ioConnectionId = response.toMap().value("params").toMap().value("ioConnectionId").toUuid();
|
||||||
|
|
||||||
|
// verify both, input and out are off
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_lightThingId);
|
||||||
|
params.insert("stateTypeId", virtualIoLightMockPowerStateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
QVERIFY2(response.toMap().value("params").toMap().value("value").toBool() == false, "Light isn't turned off");
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_ioThingId);
|
||||||
|
params.insert("stateTypeId", genericIoMockDigitalOutput1StateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
QVERIFY2(response.toMap().value("params").toMap().value("value").toBool() == false, "Digital output isn't turned off");
|
||||||
|
|
||||||
|
// Turn on light and verify digital output went on
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_lightThingId);
|
||||||
|
params.insert("actionTypeId", virtualIoLightMockPowerActionTypeId);
|
||||||
|
QVariantMap actionParam;
|
||||||
|
actionParam.insert("paramTypeId", virtualIoLightMockPowerActionPowerParamTypeId);
|
||||||
|
actionParam.insert("value", true);
|
||||||
|
params.insert("params", QVariantList() << actionParam);
|
||||||
|
response = injectAndWait("Integrations.ExecuteAction", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_ioThingId);
|
||||||
|
params.insert("stateTypeId", genericIoMockDigitalOutput1StateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
QVERIFY2(response.toMap().value("params").toMap().value("value").toBool() == true, "Digital output isn't turned on");
|
||||||
|
|
||||||
|
// Disconnect IO again
|
||||||
|
params.clear();
|
||||||
|
params.insert("ioConnectionId", ioConnectionId);
|
||||||
|
response = injectAndWait("Integrations.DisconnectIO", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
|
||||||
|
// Turn off the light and verify digital output is still on
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_lightThingId);
|
||||||
|
params.insert("actionTypeId", virtualIoLightMockPowerActionTypeId);
|
||||||
|
actionParam.clear();
|
||||||
|
actionParam.insert("paramTypeId", virtualIoLightMockPowerActionPowerParamTypeId);
|
||||||
|
actionParam.insert("value", false);
|
||||||
|
params.insert("params", QVariantList() << actionParam);
|
||||||
|
response = injectAndWait("Integrations.ExecuteAction", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_ioThingId);
|
||||||
|
params.insert("stateTypeId", genericIoMockDigitalOutput1StateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
QVERIFY2(response.toMap().value("params").toMap().value("value").toBool() == true, "Digital output turned off while it should not");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestIOConnections::testAnalogIO()
|
||||||
|
{
|
||||||
|
QVariantMap params;
|
||||||
|
params.insert("inputThingId", m_ioThingId);
|
||||||
|
params.insert("inputStateTypeId", genericIoMockAnalogInput1StateTypeId);
|
||||||
|
params.insert("outputThingId", m_tempSensorThingId);
|
||||||
|
params.insert("outputStateTypeId", virtualIoTemperatureSensorMockInputStateTypeId);
|
||||||
|
QVariant response = injectAndWait("Integrations.ConnectIO", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
IOConnectionId ioConnectionId = response.toMap().value("params").toMap().value("ioConnectionId").toUuid();
|
||||||
|
|
||||||
|
// verify input is at 0, temp at 0 too
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_ioThingId);
|
||||||
|
params.insert("stateTypeId", genericIoMockAnalogInput1StateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
QVERIFY2(qFuzzyCompare(response.toMap().value("params").toMap().value("value").toDouble(), 0), "Input isn't at 0");
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_tempSensorThingId);
|
||||||
|
params.insert("stateTypeId", virtualIoTemperatureSensorMockTemperatureStateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
QVERIFY2(qFuzzyCompare(response.toMap().value("params").toMap().value("value").toDouble(), 0), QString("Temp sensor is not at 0 but at %1").arg(response.toMap().value("params").toMap().value("value").toDouble()).toUtf8());
|
||||||
|
|
||||||
|
|
||||||
|
// set analog input to 0.5 and verify temp aligned
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_ioThingId);
|
||||||
|
params.insert("actionTypeId", genericIoMockAnalogInput1StateTypeId);
|
||||||
|
QVariantMap actionParam;
|
||||||
|
actionParam.insert("paramTypeId", genericIoMockAnalogInput1ActionAnalogInput1ParamTypeId);
|
||||||
|
actionParam.insert("value", 1.65); // goes from 0 to 3.3
|
||||||
|
params.insert("params", QVariantList() << actionParam);
|
||||||
|
response = injectAndWait("Integrations.ExecuteAction", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_tempSensorThingId);
|
||||||
|
params.insert("stateTypeId", virtualIoTemperatureSensorMockTemperatureStateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
// generic IO output goes from 0 to 3.3. We're setting 1.65V which 50%
|
||||||
|
// temp goes from -20 to 50. A input of 1.65 should output a temperature of 15°C
|
||||||
|
double expectedTemp = 70.0 / 2 - 20;
|
||||||
|
QVERIFY2(qFuzzyCompare(response.toMap().value("params").toMap().value("value").toDouble(), expectedTemp), QString("Temp sensor is not at %1 but at %2").arg(expectedTemp).arg(response.toMap().value("params").toMap().value("value").toDouble()).toUtf8());
|
||||||
|
|
||||||
|
// Disconnect IO again
|
||||||
|
params.clear();
|
||||||
|
params.insert("ioConnectionId", ioConnectionId);
|
||||||
|
response = injectAndWait("Integrations.DisconnectIO", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
|
||||||
|
// set analog input to 3 and verify temp is still at the old expectedTemp
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_ioThingId);
|
||||||
|
params.insert("actionTypeId", genericIoMockAnalogInput1StateTypeId);
|
||||||
|
actionParam.clear();
|
||||||
|
actionParam.insert("paramTypeId", genericIoMockAnalogInput1ActionAnalogInput1ParamTypeId);
|
||||||
|
actionParam.insert("value", 3); // goes from 0 to 3.3
|
||||||
|
params.insert("params", QVariantList() << actionParam);
|
||||||
|
response = injectAndWait("Integrations.ExecuteAction", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
|
||||||
|
params.clear();
|
||||||
|
params.insert("thingId", m_tempSensorThingId);
|
||||||
|
params.insert("stateTypeId", virtualIoTemperatureSensorMockTemperatureStateTypeId);
|
||||||
|
response = injectAndWait("Integrations.GetStateValue", params);
|
||||||
|
verifyThingError(response);
|
||||||
|
QVERIFY2(qFuzzyCompare(response.toMap().value("params").toMap().value("value").toDouble(), expectedTemp), QString("Temp sensor is not at %1 but at %2").arg(expectedTemp).arg(response.toMap().value("params").toMap().value("value").toDouble()).toUtf8());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "testioconnections.moc"
|
||||||
|
QTEST_MAIN(TestIOConnections)
|
||||||
|
|
||||||
Reference in New Issue
Block a user