mirror of https://github.com/nymea/nymea.git
states implemented
parent
8301500200
commit
5a6d7bf2ba
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ private:
|
|||
|
||||
private slots:
|
||||
void gotEvent(const Event &event);
|
||||
void deviceStateChanged(Device *device, const QUuid &stateTypeId, const QVariant &value);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ¶ms) 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@ public:
|
|||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ¶ms);
|
||||
|
|
|
|||
|
|
@ -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 ¶ms) 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 ¶ms)
|
|||
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 ¶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)
|
||||
{
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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 ¶ms) const;
|
||||
|
|
@ -53,11 +51,15 @@ signals:
|
|||
void commandReceived(const QString &targetNamespace, const QString &command, const QVariantMap ¶ms);
|
||||
|
||||
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 ¶ms);
|
||||
|
||||
private:
|
||||
void registerHandler(JsonHandler *handler);
|
||||
|
||||
|
|
@ -74,6 +76,8 @@ private:
|
|||
|
||||
// clientId, notificationsEnabled
|
||||
QHash<QUuid, bool> m_clients;
|
||||
|
||||
int m_notificationId;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue