add api to do async action executions
This commit is contained in:
parent
2e0dfa9947
commit
7c4354a6e1
@ -418,6 +418,7 @@ void DeviceManager::loadPlugins()
|
||||
connect(pluginIface, &DevicePlugin::emitEvent, this, &DeviceManager::emitEvent);
|
||||
connect(pluginIface, &DevicePlugin::devicesDiscovered, this, &DeviceManager::slotDevicesDiscovered);
|
||||
connect(pluginIface, &DevicePlugin::deviceSetupFinished, this, &DeviceManager::slotDeviceSetupFinished);
|
||||
connect(pluginIface, &DevicePlugin::actionExecutionFinished, this, &DeviceManager::actionExecutionFinished);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +93,7 @@ signals:
|
||||
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
|
||||
void devicesDiscovered(const DeviceClassId &deviceClassId, const QList<DeviceDescriptor> &devices);
|
||||
void deviceSetupFinished(Device *device, DeviceError status, const QString &errorMessage);
|
||||
void actionExecutionFinished(const ActionId, DeviceError status, const QString &errorMessage);
|
||||
|
||||
public slots:
|
||||
QPair<DeviceError, QString> executeAction(const Action &action);
|
||||
|
||||
@ -74,9 +74,21 @@ pure virtual methods: \l{DevicePlugin::pluginName()}, \l{DevicePlugin::pluginId(
|
||||
return report(DeviceManager::DeviceErrorSetupFailed, device->id());
|
||||
Keep the message short, the DeviceManager will format it for you.
|
||||
|
||||
\sa DevicePlugin::report()
|
||||
It is possible to execute actions asynchronously. You never should do anything blocking for
|
||||
a long time (e.g. wait on a network reply from the internet) but instead return
|
||||
DeviceManager::DeviceErrorAsync and continue processing in an async manner. Once
|
||||
you have the reply ready, emit actionExecutionFinished() with the appropriate parameters.
|
||||
|
||||
\sa DevicePlugin::report() DevicePlugin::actionExecutionFinished()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void DevicePlugin::actionExecutionFinished(const ActionId &id, DeviceManager::DeviceError status, const QString &errorMessage)
|
||||
This signal is to be emitted when you previously have returned DeviceManager::DeviceErrorAsync
|
||||
in a call of executeAction(). It is used to deliver the return value that previously has
|
||||
been omitted by filling in DeviceErrorAsync.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void DevicePlugin::emitEvent(const Event &event)
|
||||
To produce a new event in the system, create a new \l{Event} and emit it with \a event.
|
||||
|
||||
@ -71,6 +71,7 @@ signals:
|
||||
void emitEvent(const Event &event);
|
||||
void devicesDiscovered(const DeviceClassId &deviceClassId, const QList<DeviceDescriptor> &deviceDescriptors);
|
||||
void deviceSetupFinished(Device *device, DeviceManager::DeviceSetupStatus status, const QString &errorMessage);
|
||||
void actionExecutionFinished(const ActionId &id, DeviceManager::DeviceError status, const QString &errorMessage);
|
||||
|
||||
protected:
|
||||
DeviceManager *deviceManager() const;
|
||||
|
||||
@ -33,12 +33,18 @@
|
||||
#include "action.h"
|
||||
|
||||
/*! Construct an Action with the given \a deviceId and \a actionTypeId */
|
||||
Action::Action(const DeviceId &deviceId, const ActionTypeId &actionTypeId) :
|
||||
Action::Action(const ActionTypeId &actionTypeId, const DeviceId &deviceId) :
|
||||
m_id(ActionId::createActionId()),
|
||||
m_actionTypeId(actionTypeId),
|
||||
m_deviceId(deviceId)
|
||||
{
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
@ -27,7 +27,9 @@
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
explicit Action(const DeviceId &deviceId, const ActionTypeId &actionTypeId);
|
||||
explicit Action(const ActionTypeId &actionTypeId, const DeviceId &deviceId);
|
||||
|
||||
ActionId id() const;
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
@ -39,6 +41,7 @@ public:
|
||||
Param param(const QString ¶mName) const;
|
||||
|
||||
private:
|
||||
ActionId m_id;
|
||||
ActionTypeId m_actionTypeId;
|
||||
DeviceId m_deviceId;
|
||||
QList<Param> m_params;
|
||||
|
||||
@ -37,12 +37,20 @@
|
||||
the \l{Device} given by \a deviceId and the parameters given by \a params. The parameters must
|
||||
match the description in the reflecting \l{Event}.*/
|
||||
Event::Event(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList<Param> ¶ms):
|
||||
m_id(EventId::createEventId()),
|
||||
m_eventTypeId(eventTypeId),
|
||||
m_deviceId(deviceId),
|
||||
m_params(params)
|
||||
{
|
||||
}
|
||||
|
||||
/*! Returns this event's id. Each newly created event will have a new UUID generated. The id will be copied
|
||||
in the copy ctor.*/
|
||||
EventId Event::eventId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/*! Returns the id of the \l{EventType} which describes this Event.*/
|
||||
EventTypeId Event::eventTypeId() const
|
||||
{
|
||||
|
||||
@ -31,6 +31,8 @@ class Event
|
||||
public:
|
||||
Event(const EventTypeId &eventTypeId, const DeviceId &deviceId, const QList<Param> ¶ms = QList<Param>());
|
||||
|
||||
EventId eventId() const;
|
||||
|
||||
EventTypeId eventTypeId() const;
|
||||
DeviceId deviceId() const;
|
||||
|
||||
@ -41,6 +43,7 @@ public:
|
||||
bool operator ==(const Event &other) const;
|
||||
|
||||
private:
|
||||
EventId m_id;
|
||||
EventTypeId m_eventTypeId;
|
||||
DeviceId m_deviceId;
|
||||
QList<Param> m_params;
|
||||
|
||||
@ -34,11 +34,17 @@
|
||||
/*! 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 DeviceId &deviceId):
|
||||
m_id(StateId::createStateId()),
|
||||
m_stateTypeId(stateTypeId),
|
||||
m_deviceId(deviceId)
|
||||
{
|
||||
}
|
||||
|
||||
StateId State::id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
/*! Returns the id of the StateType describing this State. */
|
||||
StateTypeId State::stateTypeId() const
|
||||
{
|
||||
|
||||
@ -29,6 +29,8 @@ class State
|
||||
public:
|
||||
State(const StateTypeId &stateTypeId, const DeviceId &deviceId);
|
||||
|
||||
StateId id() const;
|
||||
|
||||
StateTypeId stateTypeId() const;
|
||||
DeviceId deviceId() const;
|
||||
|
||||
@ -37,6 +39,7 @@ public:
|
||||
void setValue(const QVariant &value);
|
||||
|
||||
private:
|
||||
StateId m_id;
|
||||
StateTypeId m_stateTypeId;
|
||||
DeviceId m_deviceId;
|
||||
QVariant m_value;
|
||||
|
||||
@ -42,8 +42,11 @@ DECLARE_TYPE_ID(Device)
|
||||
DECLARE_TYPE_ID(DeviceDescriptor)
|
||||
|
||||
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)
|
||||
|
||||
#endif // TYPEUTILS_H
|
||||
|
||||
@ -36,6 +36,8 @@ ActionHandler::ActionHandler(QObject *parent) :
|
||||
returns.insert("success", "bool");
|
||||
returns.insert("errorMessage", "string");
|
||||
setReturns("ExecuteAction", returns);
|
||||
|
||||
connect(GuhCore::instance()->deviceManager(), &DeviceManager::actionExecutionFinished, this, &ActionHandler::actionExecuted);
|
||||
}
|
||||
|
||||
QString ActionHandler::name() const
|
||||
@ -50,36 +52,58 @@ JsonReply* ActionHandler::ExecuteAction(const QVariantMap ¶ms)
|
||||
ActionTypeId actionTypeId(params.value("actionTypeId").toString());
|
||||
QList<Param> actionParams = JsonTypes::unpackParams(params.value("params").toList());
|
||||
|
||||
Action action(deviceId, actionTypeId);
|
||||
Action action(actionTypeId, deviceId);
|
||||
action.setParams(actionParams);
|
||||
|
||||
qDebug() << "actions params in json" << action.params() << params;
|
||||
|
||||
|
||||
QVariantMap returns;
|
||||
QPair<DeviceManager::DeviceError, QString> error = GuhCore::instance()->deviceManager()->executeAction(action);
|
||||
QPair<DeviceManager::DeviceError, QString> status = GuhCore::instance()->deviceManager()->executeAction(action);
|
||||
if (status.first == DeviceManager::DeviceErrorAsync) {
|
||||
JsonReply *reply = createAsyncReply("ExecuteAction");
|
||||
m_asyncActionExecutions.insert(action.id(), reply);
|
||||
return reply;
|
||||
}
|
||||
|
||||
switch (error.first) {
|
||||
QVariantMap returns = statusToReply(status.first, status.second);
|
||||
return createReply(returns);
|
||||
}
|
||||
|
||||
void ActionHandler::actionExecuted(const ActionId &id, DeviceManager::DeviceError status, const QString &errorMessage)
|
||||
{
|
||||
if (!m_asyncActionExecutions.contains(id)) {
|
||||
return; // Not the action we are waiting for.
|
||||
}
|
||||
|
||||
JsonReply *reply = m_asyncActionExecutions.take(id);
|
||||
reply->setData(statusToReply(status, errorMessage));
|
||||
reply->finished();
|
||||
}
|
||||
|
||||
QVariantMap ActionHandler::statusToReply(DeviceManager::DeviceError status, const QString &errorMessage)
|
||||
{
|
||||
QVariantMap returns;
|
||||
|
||||
switch (status) {
|
||||
case DeviceManager::DeviceErrorNoError:
|
||||
returns.insert("success", true);
|
||||
returns.insert("errorMessage", "");
|
||||
break;
|
||||
case DeviceManager::DeviceErrorDeviceNotFound:
|
||||
returns.insert("errorMessage", QString("No such device: %1").arg(error.second));
|
||||
returns.insert("errorMessage", QString("No such device: %1").arg(errorMessage));
|
||||
returns.insert("success", false);
|
||||
break;
|
||||
case DeviceManager::DeviceErrorActionTypeNotFound:
|
||||
returns.insert("errorMessage", QString("ActionType not found: %1").arg(error.second));
|
||||
returns.insert("errorMessage", QString("ActionType not found: %1").arg(errorMessage));
|
||||
returns.insert("success", false);
|
||||
break;
|
||||
case DeviceManager::DeviceErrorMissingParameter:
|
||||
returns.insert("errorMessage", QString("Missing parameter: %1").arg(error.second));
|
||||
returns.insert("errorMessage", QString("Missing parameter: %1").arg(errorMessage));
|
||||
returns.insert("success", false);
|
||||
break;
|
||||
default:
|
||||
returns.insert("errorMessage", QString("Unknown error %1 %2").arg(error.first).arg(error.second));
|
||||
returns.insert("errorMessage", QString("Unknown error %1 %2").arg(status).arg(errorMessage));
|
||||
returns.insert("success", false);
|
||||
}
|
||||
|
||||
return createReply(returns);
|
||||
return returns;
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#define ACTIONHANDLER_H
|
||||
|
||||
#include "jsonhandler.h"
|
||||
#include "devicemanager.h"
|
||||
|
||||
class ActionHandler : public JsonHandler
|
||||
{
|
||||
@ -30,6 +31,15 @@ public:
|
||||
QString name() const;
|
||||
|
||||
Q_INVOKABLE JsonReply* ExecuteAction(const QVariantMap ¶ms);
|
||||
|
||||
private slots:
|
||||
void actionExecuted(const ActionId &id, DeviceManager::DeviceError status, const QString &errorMessage);
|
||||
|
||||
private:
|
||||
QVariantMap statusToReply(DeviceManager::DeviceError status, const QString &errorMessage);
|
||||
|
||||
private:
|
||||
QHash<ActionId, JsonReply*> m_asyncActionExecutions;
|
||||
};
|
||||
|
||||
#endif // ACTIONHANDLER_H
|
||||
|
||||
@ -90,7 +90,7 @@ JsonReply* RulesHandler::AddRule(const QVariantMap ¶ms)
|
||||
qDebug() << "got action list" << actionList.count();
|
||||
foreach (const QVariant &actionVariant, actionList) {
|
||||
QVariantMap actionMap = actionVariant.toMap();
|
||||
Action action(DeviceId(actionMap.value("deviceId").toString()), ActionTypeId(actionMap.value("actionTypeId").toString()));
|
||||
Action action(ActionTypeId(actionMap.value("actionTypeId").toString()), DeviceId(actionMap.value("deviceId").toString()));
|
||||
action.setParams(JsonTypes::unpackParams(actionMap.value("params").toList()));
|
||||
actions.append(action);
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ RuleEngine::RuleEngine(QObject *parent) :
|
||||
QList<Action> actions;
|
||||
foreach (const QString &actionIdString, settings.childGroups()) {
|
||||
settings.beginGroup(actionIdString);
|
||||
Action action = Action(DeviceId(settings.value("deviceId").toString()), ActionTypeId(settings.value("actionTypeId").toString()));
|
||||
Action action = Action(ActionTypeId(settings.value("actionTypeId").toString()), DeviceId(settings.value("deviceId").toString()));
|
||||
QList<Param> params;
|
||||
foreach (QString paramNameString, settings.childGroups()) {
|
||||
if (paramNameString.startsWith("Param-")) {
|
||||
|
||||
Reference in New Issue
Block a user