states implemented
This commit is contained in:
parent
8301500200
commit
5a6d7bf2ba
@ -27,7 +27,6 @@
|
|||||||
QUuid pluginUuid = QUuid("8e0f791e-b273-4267-8605-b7c2f55a68ab");
|
QUuid pluginUuid = QUuid("8e0f791e-b273-4267-8605-b7c2f55a68ab");
|
||||||
QUuid detectorId = QUuid("bd216356-f1ec-4324-9785-6982d2174e17");
|
QUuid detectorId = QUuid("bd216356-f1ec-4324-9785-6982d2174e17");
|
||||||
QUuid inRangeStateTypeId = QUuid("cb43e1b5-4f61-4538-bfa2-c33055c542cf");
|
QUuid inRangeStateTypeId = QUuid("cb43e1b5-4f61-4538-bfa2-c33055c542cf");
|
||||||
QUuid inRangeEventTypeId = QUuid("7cae711a-a0af-41b4-b3bf-38d3e23b41ba");
|
|
||||||
|
|
||||||
DevicePluginWifiDetector::DevicePluginWifiDetector()
|
DevicePluginWifiDetector::DevicePluginWifiDetector()
|
||||||
{
|
{
|
||||||
@ -58,20 +57,6 @@ QList<DeviceClass> DevicePluginWifiDetector::supportedDevices() const
|
|||||||
|
|
||||||
deviceClassWifiDetector.setStates(detectorStates);
|
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);
|
ret.append(deviceClassWifiDetector);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -132,13 +117,6 @@ void DevicePluginWifiDetector::processFinished(int exitCode, QProcess::ExitStatu
|
|||||||
bool wasFound = foundDevices.contains(device->params().value("mac").toString().toLower());
|
bool wasFound = foundDevices.contains(device->params().value("mac").toString().toLower());
|
||||||
if (wasInRange != wasFound) {
|
if (wasInRange != wasFound) {
|
||||||
device->setStateValue(inRangeStateTypeId, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,8 +80,6 @@ GuhCore::GuhCore(QObject *parent) :
|
|||||||
m_jsonServer = new JsonRPCServer(this);
|
m_jsonServer = new JsonRPCServer(this);
|
||||||
|
|
||||||
connect(m_deviceManager, &DeviceManager::emitEvent, this, &GuhCore::gotEvent);
|
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
|
/*! Connected to the DeviceManager's emitEvent signal. Events received in
|
||||||
@ -92,8 +90,3 @@ void GuhCore::gotEvent(const Event &event)
|
|||||||
m_deviceManager->executeAction(action);
|
m_deviceManager->executeAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuhCore::deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value)
|
|
||||||
{
|
|
||||||
m_jsonServer->emitStateChangeNotification(device, stateTypeId, value);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -48,7 +48,6 @@ private:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void gotEvent(const Event &event);
|
void gotEvent(const Event &event);
|
||||||
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -17,12 +17,14 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "devicehandler.h"
|
#include "devicehandler.h"
|
||||||
|
#include "device.h"
|
||||||
#include "deviceclass.h"
|
#include "deviceclass.h"
|
||||||
#include "guhcore.h"
|
#include "guhcore.h"
|
||||||
#include "devicemanager.h"
|
#include "devicemanager.h"
|
||||||
#include "deviceplugin.h"
|
#include "deviceplugin.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
DeviceHandler::DeviceHandler(QObject *parent) :
|
DeviceHandler::DeviceHandler(QObject *parent) :
|
||||||
JsonHandler(parent)
|
JsonHandler(parent)
|
||||||
{
|
{
|
||||||
@ -91,6 +93,15 @@ DeviceHandler::DeviceHandler(QObject *parent) :
|
|||||||
actions.append(JsonTypes::actionTypeRef());
|
actions.append(JsonTypes::actionTypeRef());
|
||||||
returns.insert("actionTypes", actions);
|
returns.insert("actionTypes", actions);
|
||||||
setReturns("GetActionTypes", returns);
|
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
|
QString DeviceHandler::name() const
|
||||||
@ -200,3 +211,19 @@ QVariantMap DeviceHandler::GetActionTypes(const QVariantMap ¶ms) const
|
|||||||
returns.insert("actionTypes", actionList);
|
returns.insert("actionTypes", actionList);
|
||||||
return returns;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@ -43,6 +43,11 @@ public:
|
|||||||
|
|
||||||
Q_INVOKABLE QVariantMap GetActionTypes(const QVariantMap ¶ms) const;
|
Q_INVOKABLE QVariantMap GetActionTypes(const QVariantMap ¶ms) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void StateChanged(const QVariantMap ¶ms);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DEVICEHANDLER_H
|
#endif // DEVICEHANDLER_H
|
||||||
|
|||||||
@ -26,20 +26,42 @@ JsonHandler::JsonHandler(QObject *parent) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap JsonHandler::introspect()
|
QVariantMap JsonHandler::introspect(QMetaMethod::MethodType type)
|
||||||
{
|
{
|
||||||
QVariantMap data;
|
QVariantMap data;
|
||||||
for (int i = 0; i < metaObject()->methodCount(); ++i) {
|
for (int i = 0; i < metaObject()->methodCount(); ++i) {
|
||||||
QMetaMethod method = metaObject()->method(i);
|
QMetaMethod method = metaObject()->method(i);
|
||||||
if (method.methodType() == QMetaMethod::Method) {
|
qDebug() << "checking method" << method.methodType() << method.methodSignature() << method.name();
|
||||||
QVariantMap methodData;
|
|
||||||
|
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())) {
|
if (!m_descriptions.contains(method.name()) || !m_params.contains(method.name()) || !m_returns.contains(method.name())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
QVariantMap methodData;
|
||||||
methodData.insert("description", m_descriptions.value(method.name()));
|
methodData.insert("description", m_descriptions.value(method.name()));
|
||||||
methodData.insert("params", m_params.value(method.name()));
|
methodData.insert("params", m_params.value(method.name()));
|
||||||
methodData.insert("returns", m_returns.value(method.name()));
|
methodData.insert("returns", m_returns.value(method.name()));
|
||||||
data.insert(name() + "." + method.name(), methodData);
|
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;
|
return data;
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
#include <QMetaMethod>
|
||||||
|
|
||||||
class JsonHandler : public QObject
|
class JsonHandler : public QObject
|
||||||
{
|
{
|
||||||
@ -32,7 +33,7 @@ public:
|
|||||||
|
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
|
|
||||||
QVariantMap introspect();
|
QVariantMap introspect(QMetaMethod::MethodType);
|
||||||
|
|
||||||
bool hasMethod(const QString &methodName);
|
bool hasMethod(const QString &methodName);
|
||||||
QPair<bool, QString> validateParams(const QString &methodName, const QVariantMap ¶ms);
|
QPair<bool, QString> validateParams(const QString &methodName, const QVariantMap ¶ms);
|
||||||
|
|||||||
@ -44,10 +44,11 @@
|
|||||||
JsonRPCServer::JsonRPCServer(QObject *parent):
|
JsonRPCServer::JsonRPCServer(QObject *parent):
|
||||||
JsonHandler(parent),
|
JsonHandler(parent),
|
||||||
#ifdef TESTING_ENABLED
|
#ifdef TESTING_ENABLED
|
||||||
m_tcpServer(new MockTcpServer(this))
|
m_tcpServer(new MockTcpServer(this)),
|
||||||
#else
|
#else
|
||||||
m_tcpServer(new TcpServer(this))
|
m_tcpServer(new TcpServer(this)),
|
||||||
#endif
|
#endif
|
||||||
|
m_notificationId(0)
|
||||||
{
|
{
|
||||||
// First, define our own JSONRPC methods
|
// First, define our own JSONRPC methods
|
||||||
QVariantMap returns;
|
QVariantMap returns;
|
||||||
@ -79,27 +80,7 @@ JsonRPCServer::JsonRPCServer(QObject *parent):
|
|||||||
connect(m_tcpServer, SIGNAL(dataAvailable(const QUuid &, QByteArray)), this, SLOT(processData(const QUuid &, QByteArray)));
|
connect(m_tcpServer, SIGNAL(dataAvailable(const QUuid &, QByteArray)), this, SLOT(processData(const QUuid &, QByteArray)));
|
||||||
m_tcpServer->startServer();
|
m_tcpServer->startServer();
|
||||||
|
|
||||||
registerHandler(this);
|
QMetaObject::invokeMethod(this, "setup", Qt::QueuedConnection);
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString JsonRPCServer::name() const
|
QString JsonRPCServer::name() const
|
||||||
@ -115,10 +96,16 @@ QVariantMap JsonRPCServer::Introspect(const QVariantMap ¶ms) const
|
|||||||
data.insert("types", JsonTypes::allTypes());
|
data.insert("types", JsonTypes::allTypes());
|
||||||
QVariantMap methods;
|
QVariantMap methods;
|
||||||
foreach (JsonHandler *handler, m_handlers) {
|
foreach (JsonHandler *handler, m_handlers) {
|
||||||
// qDebug() << "got handler" << handler->name() << handler->introspect();
|
methods.unite(handler->introspect(QMetaMethod::Method));
|
||||||
methods.unite(handler->introspect());
|
|
||||||
}
|
}
|
||||||
data.insert("methods", methods);
|
data.insert("methods", methods);
|
||||||
|
|
||||||
|
QVariantMap signalsMap;
|
||||||
|
foreach (JsonHandler *handler, m_handlers) {
|
||||||
|
signalsMap.unite(handler->introspect(QMetaMethod::Signal));
|
||||||
|
}
|
||||||
|
data.insert("signals", signalsMap);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +129,14 @@ QVariantMap JsonRPCServer::SetNotificationStatus(const QVariantMap ¶ms)
|
|||||||
return returns;
|
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)
|
void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &jsonData)
|
||||||
{
|
{
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
@ -200,9 +195,29 @@ void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &jsonDat
|
|||||||
sendResponse(clientId, commandId, returns);
|
sendResponse(clientId, commandId, returns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JsonRPCServer::sendNotification(const QVariantMap ¶ms)
|
||||||
|
{
|
||||||
|
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)
|
void JsonRPCServer::registerHandler(JsonHandler *handler)
|
||||||
{
|
{
|
||||||
m_handlers.insert(handler->name(), 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)
|
void JsonRPCServer::clientConnected(const QUuid &clientId)
|
||||||
|
|||||||
@ -41,8 +41,6 @@ class JsonRPCServer: public JsonHandler
|
|||||||
public:
|
public:
|
||||||
JsonRPCServer(QObject *parent = 0);
|
JsonRPCServer(QObject *parent = 0);
|
||||||
|
|
||||||
void emitStateChangeNotification(Device *device, const QUuid &stateTypeId, const QVariant &value);
|
|
||||||
|
|
||||||
// JsonHandler API implementation
|
// JsonHandler API implementation
|
||||||
QString name() const;
|
QString name() const;
|
||||||
Q_INVOKABLE QVariantMap Introspect(const QVariantMap ¶ms) const;
|
Q_INVOKABLE QVariantMap Introspect(const QVariantMap ¶ms) const;
|
||||||
@ -53,11 +51,15 @@ signals:
|
|||||||
void commandReceived(const QString &targetNamespace, const QString &command, const QVariantMap ¶ms);
|
void commandReceived(const QString &targetNamespace, const QString &command, const QVariantMap ¶ms);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void setup();
|
||||||
|
|
||||||
void clientConnected(const QUuid &clientId);
|
void clientConnected(const QUuid &clientId);
|
||||||
void clientDisconnected(const QUuid &clientId);
|
void clientDisconnected(const QUuid &clientId);
|
||||||
|
|
||||||
void processData(const QUuid &clientId, const QByteArray &jsonData);
|
void processData(const QUuid &clientId, const QByteArray &jsonData);
|
||||||
|
|
||||||
|
void sendNotification(const QVariantMap ¶ms);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void registerHandler(JsonHandler *handler);
|
void registerHandler(JsonHandler *handler);
|
||||||
|
|
||||||
@ -74,6 +76,8 @@ private:
|
|||||||
|
|
||||||
// clientId, notificationsEnabled
|
// clientId, notificationsEnabled
|
||||||
QHash<QUuid, bool> m_clients;
|
QHash<QUuid, bool> m_clients;
|
||||||
|
|
||||||
|
int m_notificationId;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user