states implemented

pull/1/head
Michael Zanetti 2014-04-04 01:34:13 +02:00
parent 8301500200
commit 5a6d7bf2ba
9 changed files with 106 additions and 62 deletions

View File

@ -27,7 +27,6 @@
QUuid pluginUuid = QUuid("8e0f791e-b273-4267-8605-b7c2f55a68ab");
QUuid detectorId = QUuid("bd216356-f1ec-4324-9785-6982d2174e17");
QUuid inRangeStateTypeId = QUuid("cb43e1b5-4f61-4538-bfa2-c33055c542cf");
QUuid inRangeEventTypeId = QUuid("7cae711a-a0af-41b4-b3bf-38d3e23b41ba");
DevicePluginWifiDetector::DevicePluginWifiDetector()
{
@ -58,20 +57,6 @@ QList<DeviceClass> DevicePluginWifiDetector::supportedDevices() const
deviceClassWifiDetector.setStates(detectorStates);
QList<EventType> detectorEvents;
QVariantList detectorEventParams;
QVariantMap paramInRange;
paramInRange.insert("name", "inRange");
paramInRange.insert("type", "bool");
detectorEventParams.append(paramInRange);
EventType inRangeEvent(inRangeEventTypeId);
inRangeEvent.setName("inRange");
inRangeEvent.setParameters(detectorEventParams);
detectorEvents.append(inRangeEvent);
deviceClassWifiDetector.setEvents(detectorEvents);
ret.append(deviceClassWifiDetector);
return ret;
@ -132,13 +117,6 @@ void DevicePluginWifiDetector::processFinished(int exitCode, QProcess::ExitStatu
bool wasFound = foundDevices.contains(device->params().value("mac").toString().toLower());
if (wasInRange != wasFound) {
device->setStateValue(inRangeStateTypeId, wasFound);
QVariantMap params;
params.insert("inRange", wasFound);
Event event(inRangeEventTypeId, device->id(), params);
qDebug() << "Device" << device->name() << QStringLiteral("is now ") + (wasFound ? "in" : "out of") + " range";
emit emitEvent(event);
}
}
}

View File

@ -80,8 +80,6 @@ GuhCore::GuhCore(QObject *parent) :
m_jsonServer = new JsonRPCServer(this);
connect(m_deviceManager, &DeviceManager::emitEvent, this, &GuhCore::gotEvent);
connect(m_deviceManager, &DeviceManager::deviceStateChanged, this, &GuhCore::deviceStateChanged);
}
/*! Connected to the DeviceManager's emitEvent signal. Events received in
@ -92,8 +90,3 @@ void GuhCore::gotEvent(const Event &event)
m_deviceManager->executeAction(action);
}
}
void GuhCore::deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value)
{
m_jsonServer->emitStateChangeNotification(device, stateTypeId, value);
}

View File

@ -48,7 +48,6 @@ private:
private slots:
void gotEvent(const Event &event);
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
};

View File

@ -17,12 +17,14 @@
***************************************************************************/
#include "devicehandler.h"
#include "device.h"
#include "deviceclass.h"
#include "guhcore.h"
#include "devicemanager.h"
#include "deviceplugin.h"
#include <QDebug>
DeviceHandler::DeviceHandler(QObject *parent) :
JsonHandler(parent)
{
@ -91,6 +93,15 @@ DeviceHandler::DeviceHandler(QObject *parent) :
actions.append(JsonTypes::actionTypeRef());
returns.insert("actionTypes", actions);
setReturns("GetActionTypes", returns);
params.clear(); returns.clear();
setDescription("StateChanged", "Emitted whenever a State of a device changes.");
params.insert("deviceId", "uuid");
params.insert("stateTypeId", "uuid");
params.insert("variant", "value");
setParams("StateChanged", params);
connect(GuhCore::instance()->deviceManager(), &DeviceManager::deviceStateChanged, this, &DeviceHandler::deviceStateChanged);
}
QString DeviceHandler::name() const
@ -200,3 +211,19 @@ QVariantMap DeviceHandler::GetActionTypes(const QVariantMap &params) const
returns.insert("actionTypes", actionList);
return returns;
}
void DeviceHandler::deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value)
{
qDebug() << "************************************";
QVariantMap notification;
notification.insert("notification", "Device.StateChanged");
QVariantMap params;
params.insert("deviceId", device->id());
params.insert("stateTypeId", stateTypeId);
params.insert("value", value);
notification.insert("params", params);
emit StateChanged(notification);
}

View File

@ -43,6 +43,11 @@ public:
Q_INVOKABLE QVariantMap GetActionTypes(const QVariantMap &params) const;
signals:
void StateChanged(const QVariantMap &params);
private slots:
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
};
#endif // DEVICEHANDLER_H

View File

@ -26,20 +26,42 @@ JsonHandler::JsonHandler(QObject *parent) :
{
}
QVariantMap JsonHandler::introspect()
QVariantMap JsonHandler::introspect(QMetaMethod::MethodType type)
{
QVariantMap data;
for (int i = 0; i < metaObject()->methodCount(); ++i) {
QMetaMethod method = metaObject()->method(i);
if (method.methodType() == QMetaMethod::Method) {
QVariantMap methodData;
qDebug() << "checking method" << method.methodType() << method.methodSignature() << method.name();
if (method.methodType() != type) {
continue;
}
switch (method.methodType()) {
case QMetaMethod::Method: {
if (!m_descriptions.contains(method.name()) || !m_params.contains(method.name()) || !m_returns.contains(method.name())) {
continue;
}
QVariantMap methodData;
methodData.insert("description", m_descriptions.value(method.name()));
methodData.insert("params", m_params.value(method.name()));
methodData.insert("returns", m_returns.value(method.name()));
data.insert(name() + "." + method.name(), methodData);
break;
}
case QMetaMethod::Signal: {
if (!m_descriptions.contains(method.name()) || !m_params.contains(method.name())) {
continue;
}
if (QString(method.name()).contains(QRegExp("^[A-Z]"))) {
qDebug() << "got signal" << method.name();
QVariantMap methodData;
methodData.insert("description", m_descriptions.value(method.name()));
methodData.insert("params", m_params.value(method.name()));
data.insert(name() + "." + method.name(), methodData);
}
break;
}
}
}
return data;

View File

@ -23,6 +23,7 @@
#include <QObject>
#include <QVariantMap>
#include <QMetaMethod>
class JsonHandler : public QObject
{
@ -32,7 +33,7 @@ public:
virtual QString name() const = 0;
QVariantMap introspect();
QVariantMap introspect(QMetaMethod::MethodType);
bool hasMethod(const QString &methodName);
QPair<bool, QString> validateParams(const QString &methodName, const QVariantMap &params);

View File

@ -44,10 +44,11 @@
JsonRPCServer::JsonRPCServer(QObject *parent):
JsonHandler(parent),
#ifdef TESTING_ENABLED
m_tcpServer(new MockTcpServer(this))
m_tcpServer(new MockTcpServer(this)),
#else
m_tcpServer(new TcpServer(this))
m_tcpServer(new TcpServer(this)),
#endif
m_notificationId(0)
{
// First, define our own JSONRPC methods
QVariantMap returns;
@ -79,27 +80,7 @@ JsonRPCServer::JsonRPCServer(QObject *parent):
connect(m_tcpServer, SIGNAL(dataAvailable(const QUuid &, QByteArray)), this, SLOT(processData(const QUuid &, QByteArray)));
m_tcpServer->startServer();
registerHandler(this);
registerHandler(new DeviceHandler(this));
registerHandler(new ActionHandler(this));
registerHandler(new RulesHandler(this));
}
void JsonRPCServer::emitStateChangeNotification(Device *device, const QUuid &stateTypeId, const QVariant &value)
{
QVariantMap notification;
notification.insert("notification", "Device.StateChanged");
QVariantMap params;
params.insert("deviceId", device->id());
params.insert("stateTypeId", stateTypeId);
params.insert("value", value);
notification.insert("params", params);
QJsonDocument jsonDoc = QJsonDocument::fromVariant(notification);
m_tcpServer->sendData(m_clients.keys(true), jsonDoc.toJson());
QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);
}
QString JsonRPCServer::name() const
@ -115,10 +96,16 @@ QVariantMap JsonRPCServer::Introspect(const QVariantMap &params) const
data.insert("types", JsonTypes::allTypes());
QVariantMap methods;
foreach (JsonHandler *handler, m_handlers) {
// qDebug() << "got handler" << handler->name() << handler->introspect();
methods.unite(handler->introspect());
methods.unite(handler->introspect(QMetaMethod::Method));
}
data.insert("methods", methods);
QVariantMap signalsMap;
foreach (JsonHandler *handler, m_handlers) {
signalsMap.unite(handler->introspect(QMetaMethod::Signal));
}
data.insert("signals", signalsMap);
return data;
}
@ -142,6 +129,14 @@ QVariantMap JsonRPCServer::SetNotificationStatus(const QVariantMap &params)
return returns;
}
void JsonRPCServer::setup()
{
registerHandler(this);
registerHandler(new DeviceHandler(this));
registerHandler(new ActionHandler(this));
registerHandler(new RulesHandler(this));
}
void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &jsonData)
{
QJsonParseError error;
@ -200,9 +195,29 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &jsonDat
sendResponse(clientId, commandId, returns);
}
void JsonRPCServer::sendNotification(const QVariantMap &params)
{
JsonHandler *handler = qobject_cast<JsonHandler*>(sender());
QMetaMethod method = handler->metaObject()->method(senderSignalIndex());
QVariantMap notification;
notification.insert("id", m_notificationId++);
notification.insert("notification", handler->name() + "." + method.name());
notification.insert("params", params);
QJsonDocument jsonDoc = QJsonDocument::fromVariant(notification);
m_tcpServer->sendData(m_clients.keys(true), jsonDoc.toJson());
}
void JsonRPCServer::registerHandler(JsonHandler *handler)
{
m_handlers.insert(handler->name(), handler);
for (int i = 0; i < handler->metaObject()->methodCount(); ++i) {
QMetaMethod method = handler->metaObject()->method(i);
if (method.methodType() == QMetaMethod::Signal && QString(method.name()).contains(QRegExp("^[A-Z]"))) {
QObject::connect(handler, method, this, metaObject()->method(metaObject()->indexOfSlot("sendNotification(QVariantMap)")));
}
}
}
void JsonRPCServer::clientConnected(const QUuid &clientId)

View File

@ -41,8 +41,6 @@ class JsonRPCServer: public JsonHandler
public:
JsonRPCServer(QObject *parent = 0);
void emitStateChangeNotification(Device *device, const QUuid &stateTypeId, const QVariant &value);
// JsonHandler API implementation
QString name() const;
Q_INVOKABLE QVariantMap Introspect(const QVariantMap &params) const;
@ -53,11 +51,15 @@ signals:
void commandReceived(const QString &targetNamespace, const QString &command, const QVariantMap &params);
private slots:
void setup();
void clientConnected(const QUuid &clientId);
void clientDisconnected(const QUuid &clientId);
void processData(const QUuid &clientId, const QByteArray &jsonData);
void sendNotification(const QVariantMap &params);
private:
void registerHandler(JsonHandler *handler);
@ -74,6 +76,8 @@ private:
// clientId, notificationsEnabled
QHash<QUuid, bool> m_clients;
int m_notificationId;
};
#endif