From 21738b3907735ac2858ddccb22fb19d3a6998e22 Mon Sep 17 00:00:00 2001 From: Michael Zanetti Date: Sun, 8 Jun 2014 20:47:07 +0200 Subject: [PATCH] state changes emit events now --- debian/changelog | 10 +++- libguh/devicemanager.cpp | 10 +++- libguh/plugin/device.cpp | 1 + libguh/plugin/deviceclass.cpp | 56 ++++++++++++------- libguh/plugin/deviceclass.h | 29 +++++----- libguh/types/eventtype.cpp | 10 ++-- libguh/types/eventtype.h | 7 ++- .../boblight/devicepluginboblight.cpp | 2 +- .../conrad/devicepluginconrad.cpp | 19 +++---- .../deviceplugins/elro/devicepluginelro.cpp | 14 ++--- .../intertechno/devicepluginintertechno.cpp | 15 ++--- .../deviceplugins/lircd/devicepluginlircd.cpp | 14 ++--- .../devicepluginmailnotification.cpp | 4 +- .../deviceplugins/mock/devicepluginmock.cpp | 36 ++++++------ plugins/deviceplugins/mock/httpdaemon.cpp | 19 ++++--- .../devicepluginopenweathermap.cpp | 6 +- .../wakeonlan/devicepluginwakeonlan.cpp | 2 +- .../wifidetector/devicepluginwifidetector.cpp | 4 +- server/guhcore.cpp | 4 ++ server/guhcore.h | 3 + server/jsonrpc/actionhandler.cpp | 2 +- server/jsonrpc/devicehandler.cpp | 6 +- server/jsonrpc/eventhandler.cpp | 48 ++++++++++++++++ server/jsonrpc/eventhandler.h | 38 +++++++++++++ server/jsonrpc/jsonrpcserver.cpp | 2 + server/jsonrpc/jsontypes.cpp | 16 ++++-- server/ruleengine.cpp | 2 +- server/server.pri | 6 +- tests/auto/api.json | 8 ++- tests/auto/devices/testdevices.cpp | 2 +- tests/auto/jsonrpc/testjsonrpc.cpp | 8 ++- 31 files changed, 270 insertions(+), 133 deletions(-) create mode 100644 server/jsonrpc/eventhandler.cpp create mode 100644 server/jsonrpc/eventhandler.h diff --git a/debian/changelog b/debian/changelog index ff41c2c9..893fb0ab 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,14 @@ -guh (0.1.5) UNRELEASED; urgency=medium +guh (0.1.6) utopic; urgency=medium + + * state changes auto generate events now + + -- Michael Zanetti Sun, 08 Jun 2014 20:28:17 +0200 + +guh (0.1.5) utopic; urgency=medium * align params/paramTypes with the rest of the type system - -- Michael Zanetti Sun, 08 Jun 2014 16:36:27 +0200 + -- Michael Zanetti Sun, 08 Jun 2014 20:24:25 +0200 guh (0.1.4) trusty; urgency=medium diff --git a/libguh/devicemanager.cpp b/libguh/devicemanager.cpp index b1dfa535..d5138466 100644 --- a/libguh/devicemanager.cpp +++ b/libguh/devicemanager.cpp @@ -241,7 +241,7 @@ QPair DeviceManager::addConfiguredDeviceInt return qMakePair(DeviceErrorDeviceClassNotFound, deviceClassId.toString()); } - QPair result = verifyParams(deviceClass.params(), params); + QPair result = verifyParams(deviceClass.paramTypes(), params); if (result.first != DeviceErrorNoError) { return result; } @@ -360,7 +360,7 @@ QPair DeviceManager::executeAction(const Ac // Make sure this device has an action type with this id DeviceClass deviceClass = findDeviceClass(device->deviceClassId()); bool found = false; - foreach (const ActionType &actionType, deviceClass.actions()) { + foreach (const ActionType &actionType, deviceClass.actionTypes()) { if (actionType.id() == action.actionTypeId()) { QPair paramCheck = verifyParams(actionType.parameters(), action.params()); if (paramCheck.first != DeviceErrorNoError) { @@ -593,6 +593,10 @@ void DeviceManager::slotDeviceStateValueChanged(const QUuid &stateTypeId, const return; } emit deviceStateChanged(device, stateTypeId, value); + + Param valueParam("value", value); + Event event(EventTypeId(stateTypeId.toString()), device->id(), QList() << valueParam); + emit eventTriggered(event); } void DeviceManager::radio433SignalReceived(QList rawData) @@ -627,7 +631,7 @@ QPair DeviceManager::setupDevice(Devic } QList states; - foreach (const StateType &stateType, deviceClass.states()) { + foreach (const StateType &stateType, deviceClass.stateTypes()) { State state(stateType.id(), device->id()); state.setValue(stateType.defaultValue()); states.append(state); diff --git a/libguh/plugin/device.cpp b/libguh/plugin/device.cpp index c5828721..5a32224c 100644 --- a/libguh/plugin/device.cpp +++ b/libguh/plugin/device.cpp @@ -30,6 +30,7 @@ */ #include "device.h" +#include "types/event.h" #include diff --git a/libguh/plugin/deviceclass.cpp b/libguh/plugin/deviceclass.cpp index e605d741..26e4a5ec 100644 --- a/libguh/plugin/deviceclass.cpp +++ b/libguh/plugin/deviceclass.cpp @@ -87,68 +87,86 @@ void DeviceClass::setName(const QString &name) /*! Returns the statesTypes of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their states matching to this template. */ -QList DeviceClass::states() const +QList DeviceClass::stateTypes() const { - return m_states; + return m_stateTypes; } /*! Set the \a stateTypes of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their states matching to this template. */ -void DeviceClass::setStates(const QList &stateTypes) +void DeviceClass::setStateTypes(const QList &stateTypes) { - m_states = stateTypes; + m_stateTypes = stateTypes; + + m_allEventTypes = m_eventTypes; + foreach (const StateType &stateType, m_stateTypes) { + EventType eventType(EventTypeId(stateType.id().toString())); + eventType.setName(QString("%1 changed").arg(stateType.name())); + ParamType paramType("value", stateType.type()); + eventType.setParameters(QList() << paramType); + m_allEventTypes.append(eventType); + } } /*! Returns the eventTypes of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their events matching to this template. */ -QList DeviceClass::events() const +QList DeviceClass::eventTypes() const { - return m_events; + return m_allEventTypes; } /*! Set the \a eventTypes of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their events matching to this template. */ -void DeviceClass::setEvents(const QList &eventTypes) +void DeviceClass::setEventTypes(const QList &eventTypes) { - m_events = eventTypes; + m_eventTypes = eventTypes; + + m_allEventTypes = m_eventTypes; + foreach (const StateType &stateType, m_stateTypes) { + EventType eventType(EventTypeId(stateType.id().toString())); + eventType.setName(QString("%1 changed").arg(stateType.name())); + ParamType paramType("value", stateType.type()); + eventType.setParameters(QList() << paramType); + m_allEventTypes.append(eventType); + } } /*! Returns the actionTypes of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their actions matching to this template. */ -QList DeviceClass::actions() const +QList DeviceClass::actionTypes() const { - return m_actions; + return m_actionTypes; } /*! Set the \a actionTypes of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their actions matching to this template. */ void DeviceClass::setActions(const QList &actionTypes) { - m_actions = actionTypes; + m_actionTypes = actionTypes; } /*! Returns the params description of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their params matching to this template. */ -QList DeviceClass::params() const +QList DeviceClass::paramTypes() const { - return m_params; + return m_paramTypes; } /*! Set the \a params of this DeviceClass. \{Device}{Devices} created from this DeviceClass must have their actions matching to this template. */ -void DeviceClass::setParams(const QList ¶ms) +void DeviceClass::setParamTypes(const QList ¶ms) { - m_params = params; + m_paramTypes = params; } -QList DeviceClass::discoveryParams() const +QList DeviceClass::discoveryParamTypes() const { - return m_discoveryParams; + return m_discoveryParamTypes; } -void DeviceClass::setDiscoveryParams(const QList ¶ms) +void DeviceClass::setDiscoveryParamTypes(const QList ¶ms) { - m_discoveryParams = params; + m_discoveryParamTypes = params; } DeviceClass::CreateMethod DeviceClass::createMethod() const diff --git a/libguh/plugin/deviceclass.h b/libguh/plugin/deviceclass.h index dc54435f..7ccc8964 100644 --- a/libguh/plugin/deviceclass.h +++ b/libguh/plugin/deviceclass.h @@ -54,20 +54,20 @@ public: QString name() const; void setName(const QString &name); - QList states() const; - void setStates(const QList &stateTypes); + QList stateTypes() const; + void setStateTypes(const QList &stateTypes); - QList events() const; - void setEvents(const QList &eventTypes); + QList eventTypes() const; + void setEventTypes(const QList &eventTypes); - QList actions() const; + QList actionTypes() const; void setActions(const QList &actionTypes); - QList params() const; - void setParams(const QList ¶ms); + QList paramTypes() const; + void setParamTypes(const QList ¶mTypes); - QList discoveryParams() const; - void setDiscoveryParams(const QList ¶ms); + QList discoveryParamTypes() const; + void setDiscoveryParamTypes(const QList ¶mTypes); CreateMethod createMethod() const; void setCreateMethod(CreateMethod createMethod); @@ -81,11 +81,12 @@ private: VendorId m_vendorId; PluginId m_pluginId; QString m_name; - QList m_states; - QList m_events; - QList m_actions; - QList m_params; - QList m_discoveryParams; + QList m_stateTypes; + QList m_eventTypes; + QList m_allEventTypes; + QList m_actionTypes; + QList m_paramTypes; + QList m_discoveryParamTypes; CreateMethod m_createMethod; SetupMethod m_setupMethod; }; diff --git a/libguh/types/eventtype.cpp b/libguh/types/eventtype.cpp index 67ad5291..547914d8 100644 --- a/libguh/types/eventtype.cpp +++ b/libguh/types/eventtype.cpp @@ -53,19 +53,19 @@ void EventType::setName(const QString &name) } /*! - Holds a map describing possible parameters for a \l{Event} of this EventType. - e.g. QVariantList(QVariantMap(("name", "temperature"), ("type": QVariant::Real))) + Holds a List describing possible parameters for a \l{Event} of this EventType. + e.g. QList(ParamType("temperature", QVariant::Real)) */ -QVariantList EventType::parameters() const +QList EventType::parameters() const { return m_parameters; } /*! Set the parameter description for this EventType to \a parameters, - e.g. QVariantList(QVariantMap(("name", "temperature"), ("type": QVariant::Real))) + e.g. QList() << ParamType("temperature", QVariant::Real)) */ -void EventType::setParameters(const QVariantList ¶meters) +void EventType::setParameters(const QList ¶meters) { m_parameters = parameters; } diff --git a/libguh/types/eventtype.h b/libguh/types/eventtype.h index 39037c5d..1165f91a 100644 --- a/libguh/types/eventtype.h +++ b/libguh/types/eventtype.h @@ -20,6 +20,7 @@ #define TRIGGERTYPE_H #include "typeutils.h" +#include "paramtype.h" #include @@ -33,14 +34,14 @@ public: QString name() const; void setName(const QString &name); - QVariantList parameters() const; - void setParameters(const QVariantList ¶meters); + QList parameters() const; + void setParameters(const QList ¶meters); private: EventTypeId m_id; QString m_name; - QVariantList m_parameters; + QList m_parameters; }; diff --git a/plugins/deviceplugins/boblight/devicepluginboblight.cpp b/plugins/deviceplugins/boblight/devicepluginboblight.cpp index eedb7111..9f6c8186 100644 --- a/plugins/deviceplugins/boblight/devicepluginboblight.cpp +++ b/plugins/deviceplugins/boblight/devicepluginboblight.cpp @@ -63,7 +63,7 @@ QList DevicePluginBoblight::supportedDevices() const colorState.setDefaultValue(QColor(Qt::black)); boblightStates.append(colorState); - deviceClassBoblight.setStates(boblightStates); + deviceClassBoblight.setStateTypes(boblightStates); QList boblightActons; diff --git a/plugins/deviceplugins/conrad/devicepluginconrad.cpp b/plugins/deviceplugins/conrad/devicepluginconrad.cpp index bbef79ca..1ba9e596 100644 --- a/plugins/deviceplugins/conrad/devicepluginconrad.cpp +++ b/plugins/deviceplugins/conrad/devicepluginconrad.cpp @@ -55,6 +55,7 @@ #include "devicemanager.h" #include "plugin/device.h" #include "hardware/radio433.h" +#include "types/paramtype.h" #include #include @@ -98,20 +99,14 @@ QList DevicePluginConrad::supportedDevices() const // Events QList buttonEvents; - QVariantList paramsRemote; - QVariantMap paramButton; - paramButton.insert("name", "button"); - paramButton.insert("type", "int"); + QList paramsRemote; + ParamType paramButton("button", QVariant::Int); paramsRemote.append(paramButton); - QVariantMap paramGroup; - paramGroup.insert("name", "group"); - paramGroup.insert("type", "int"); + ParamType paramGroup("group", QVariant::Int); paramsRemote.append(paramGroup); - QVariantMap paramPower; - paramPower.insert("name", "power"); - paramPower.insert("type", "bool"); + ParamType paramPower("power", QVariant::Bool); paramsRemote.append(paramPower); EventType buttonEvent(conradRemoteButtonEventTypeId); @@ -119,8 +114,8 @@ QList DevicePluginConrad::supportedDevices() const buttonEvent.setParameters(paramsRemote); buttonEvents.append(buttonEvent); - deviceClassConradRemote.setParams(deviceParamsRemote); - deviceClassConradRemote.setEvents(buttonEvents); + deviceClassConradRemote.setParamTypes(deviceParamsRemote); + deviceClassConradRemote.setEventTypes(buttonEvents); ret.append(deviceClassConradRemote); return ret; diff --git a/plugins/deviceplugins/elro/devicepluginelro.cpp b/plugins/deviceplugins/elro/devicepluginelro.cpp index 57d0b02e..3b5fa73b 100644 --- a/plugins/deviceplugins/elro/devicepluginelro.cpp +++ b/plugins/deviceplugins/elro/devicepluginelro.cpp @@ -105,14 +105,12 @@ QList DevicePluginElro::supportedDevices() const channelParam = ParamType("channel5", QVariant::Bool); deviceParamsRemote.append(channelParam); - deviceClassElroRemote.setParams(deviceParamsRemote); + deviceClassElroRemote.setParamTypes(deviceParamsRemote); QList buttonEvents; - QVariantList paramsRemote; - QVariantMap param; - param.insert("name", "power"); - param.insert("type", "bool"); + QList paramsRemote; + ParamType param("power", QVariant::Bool); paramsRemote.append(param); EventType buttonAEvent(EventTypeId("9dd3f862-35f3-4b69-954e-fa3c8bd68e39")); @@ -140,7 +138,7 @@ QList DevicePluginElro::supportedDevices() const buttonEEvent.setParameters(paramsRemote); buttonEvents.append(buttonEEvent); - deviceClassElroRemote.setEvents(buttonEvents); + deviceClassElroRemote.setEventTypes(buttonEvents); ret.append(deviceClassElroRemote); // ======================================= @@ -184,7 +182,7 @@ QList DevicePluginElro::supportedDevices() const paramSwitch = ParamType("E", QVariant::Bool); deviceParamsSwitch.append(paramSwitch); - deviceClassElroSwitch.setParams(deviceParamsSwitch); + deviceClassElroSwitch.setParamTypes(deviceParamsSwitch); QList actionParamsSwitch; @@ -436,7 +434,7 @@ void DevicePluginElro::radioData(QList rawData) // FIXME: find a better way to get to the remote DeviceClass DeviceClass deviceClass = supportedDevices().first(); - foreach (const EventType &eventType, deviceClass.events()) { + foreach (const EventType &eventType, deviceClass.eventTypes()) { if (eventType.name() == button) { //qDebug() << "emit event " << pluginName() << group << eventType.name() << power; Event event = Event(eventType.id(), device->id(), params); diff --git a/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp b/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp index 29ab73d4..21dad455 100644 --- a/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp +++ b/plugins/deviceplugins/intertechno/devicepluginintertechno.cpp @@ -194,17 +194,14 @@ QList DevicePluginIntertechno::supportedDevices() const ParamType familyParam("familyCode", QVariant::String); remoteParams.append(familyParam); - deviceClassIntertechnoRemote.setParams(remoteParams); + deviceClassIntertechnoRemote.setParamTypes(remoteParams); QList buttonEvents; - QVariantList paramsRemote; - QVariantMap paramRemote; - + QList paramsRemote; // on = true // off = false - paramRemote.insert("name", "power"); - paramRemote.insert("type", "bool"); + ParamType paramRemote("power", QVariant::Bool); paramsRemote.append(paramRemote); /* 1-16 @@ -298,7 +295,7 @@ QList DevicePluginIntertechno::supportedDevices() const button16Event.setParameters(paramsRemote); buttonEvents.append(button16Event); - deviceClassIntertechnoRemote.setEvents(buttonEvents); + deviceClassIntertechnoRemote.setEventTypes(buttonEvents); ret.append(deviceClassIntertechnoRemote); @@ -314,7 +311,7 @@ QList DevicePluginIntertechno::supportedDevices() const switchDeviceParams.append(familyParam); switchDeviceParams.append(buttonParam); - deviceClassIntertechnoSwitch.setParams(switchDeviceParams); + deviceClassIntertechnoSwitch.setParamTypes(switchDeviceParams); QList switchActions; @@ -695,7 +692,7 @@ void DevicePluginIntertechno::radioData(QList rawData) // FIXME: find a better way to get to the remote DeviceClass DeviceClass deviceClass = supportedDevices().first(); - foreach (const EventType &eventType, deviceClass.events()) { + foreach (const EventType &eventType, deviceClass.eventTypes()) { if (eventType.name() == buttonCode) { qDebug() << "emit event " << pluginName() << familyCode << eventType.name() << power; Event event = Event(eventType.id(), device->id(), params); diff --git a/plugins/deviceplugins/lircd/devicepluginlircd.cpp b/plugins/deviceplugins/lircd/devicepluginlircd.cpp index 1715993c..2a6399d3 100644 --- a/plugins/deviceplugins/lircd/devicepluginlircd.cpp +++ b/plugins/deviceplugins/lircd/devicepluginlircd.cpp @@ -58,15 +58,13 @@ QList DevicePluginLircd::supportedDevices() const QList params; ParamType remoteNameParam("remoteName", QVariant::String); params.append(remoteNameParam); - deviceClassLircd.setParams(params); + deviceClassLircd.setParamTypes(params); // TODO: find a way to load this stuff from a json file, really! // Ideally that file can be generated from /usr/share/lirc/remotes/* // Note that the IDs need to be kept static! - QVariantList repeatParam; - QVariantMap repeatParamMap; - repeatParamMap.insert("name", "repeat"); - repeatParamMap.insert("type", "int"); + QList repeatParam; + ParamType repeatParamMap("repeat", QVariant::Int); repeatParam.append(repeatParamMap); QList events; @@ -91,7 +89,7 @@ QList DevicePluginLircd::supportedDevices() const redButton.setParameters(repeatParam); events.append(redButton); - deviceClassLircd.setEvents(events); + deviceClassLircd.setEventTypes(events); ret.append(deviceClassLircd); @@ -128,8 +126,8 @@ void DevicePluginLircd::buttonPressed(const QString &remoteName, const QString & return; } - qDebug() << "found remote" << remoteName << supportedDevices().first().events().count(); - foreach (const EventType &eventType, supportedDevices().first().events()) { + qDebug() << "found remote" << remoteName << supportedDevices().first().eventTypes().count(); + foreach (const EventType &eventType, supportedDevices().first().eventTypes()) { if (eventType.name() == buttonName) { QList params; Param param("repeat", repeat); diff --git a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp index 2987d2d6..755d2c0f 100644 --- a/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp +++ b/plugins/deviceplugins/mailnotification/devicepluginmailnotification.cpp @@ -295,7 +295,7 @@ QList DevicePluginMailNotification::supportedDevices() const googleMailParams.append(recipientGoogleParam); deviceClassGoogleMail.setActions(mailActions); - deviceClassGoogleMail.setParams(googleMailParams); + deviceClassGoogleMail.setParamTypes(googleMailParams); // Custom Mail // --------------------------------------------------------------- @@ -325,7 +325,7 @@ QList DevicePluginMailNotification::supportedDevices() const customMailParams.append(authCustomParam); deviceClassCustomMail.setActions(mailActions); - deviceClassCustomMail.setParams(customMailParams); + deviceClassCustomMail.setParamTypes(customMailParams); ret.append(deviceClassGoogleMail); ret.append(deviceClassCustomMail); diff --git a/plugins/deviceplugins/mock/devicepluginmock.cpp b/plugins/deviceplugins/mock/devicepluginmock.cpp index 87db94dd..b6034581 100644 --- a/plugins/deviceplugins/mock/devicepluginmock.cpp +++ b/plugins/deviceplugins/mock/devicepluginmock.cpp @@ -70,7 +70,7 @@ QList DevicePluginMock::supportedDevices() const ParamType portParam("httpport", QVariant::Int); mockParams.append(portParam); - deviceClassMock.setParams(mockParams); + deviceClassMock.setParamTypes(mockParams); QList mockStates; @@ -86,7 +86,7 @@ QList DevicePluginMock::supportedDevices() const boolState.setDefaultValue(false); mockStates.append(boolState); - deviceClassMock.setStates(mockStates); + deviceClassMock.setStateTypes(mockStates); QList mockEvents; @@ -98,7 +98,7 @@ QList DevicePluginMock::supportedDevices() const event2.setName("Mock Event 2"); mockEvents.append(event2); - deviceClassMock.setEvents(mockEvents); + deviceClassMock.setEventTypes(mockEvents); QList mockActions; @@ -138,9 +138,9 @@ QList DevicePluginMock::supportedDevices() const deviceClassMockAuto.setCreateMethod(DeviceClass::CreateMethodAuto); mockParams.clear(); - deviceClassMockAuto.setParams(mockParams); - deviceClassMockAuto.setStates(mockStates); - deviceClassMockAuto.setEvents(mockEvents); + deviceClassMockAuto.setParamTypes(mockParams); + deviceClassMockAuto.setStateTypes(mockStates); + deviceClassMockAuto.setEventTypes(mockEvents); deviceClassMockAuto.setActions(mockActions); ret.append(deviceClassMockAuto); @@ -152,9 +152,9 @@ QList DevicePluginMock::supportedDevices() const mockParams.clear(); mockParams.append(portParam); - deviceClassMockDiscovery.setParams(mockParams); - deviceClassMockDiscovery.setStates(mockStates); - deviceClassMockDiscovery.setEvents(mockEvents); + deviceClassMockDiscovery.setParamTypes(mockParams); + deviceClassMockDiscovery.setStateTypes(mockStates); + deviceClassMockDiscovery.setEventTypes(mockEvents); deviceClassMockDiscovery.setActions(mockActions); ret.append(deviceClassMockDiscovery); @@ -164,9 +164,9 @@ QList DevicePluginMock::supportedDevices() const deviceClassMockAsync.setName("Mock Device (Async)"); deviceClassMockAsync.setCreateMethod(DeviceClass::CreateMethodUser); - deviceClassMockAsync.setParams(mockParams); - deviceClassMockAsync.setStates(mockStates); - deviceClassMockAsync.setEvents(mockEvents); + deviceClassMockAsync.setParamTypes(mockParams); + deviceClassMockAsync.setStateTypes(mockStates); + deviceClassMockAsync.setEventTypes(mockEvents); deviceClassMockAsync.setActions(mockActions); ret.append(deviceClassMockAsync); @@ -176,9 +176,9 @@ QList DevicePluginMock::supportedDevices() const deviceClassMockBroken.setName("Mock Device (Broken setup)"); deviceClassMockBroken.setCreateMethod(DeviceClass::CreateMethodUser); - deviceClassMockBroken.setParams(mockParams); - deviceClassMockBroken.setStates(mockStates); - deviceClassMockBroken.setEvents(mockEvents); + deviceClassMockBroken.setParamTypes(mockParams); + deviceClassMockBroken.setStateTypes(mockStates); + deviceClassMockBroken.setEventTypes(mockEvents); deviceClassMockBroken.setActions(mockActions); ret.append(deviceClassMockBroken); @@ -188,9 +188,9 @@ QList DevicePluginMock::supportedDevices() const deviceClassMockBrokenAsyncSetup.setName("Mock Device (Async Broken setup)"); deviceClassMockBrokenAsyncSetup.setCreateMethod(DeviceClass::CreateMethodUser); - deviceClassMockBrokenAsyncSetup.setParams(mockParams); - deviceClassMockBrokenAsyncSetup.setStates(mockStates); - deviceClassMockBrokenAsyncSetup.setEvents(mockEvents); + deviceClassMockBrokenAsyncSetup.setParamTypes(mockParams); + deviceClassMockBrokenAsyncSetup.setStateTypes(mockStates); + deviceClassMockBrokenAsyncSetup.setEventTypes(mockEvents); deviceClassMockBrokenAsyncSetup.setActions(mockActions); ret.append(deviceClassMockBrokenAsyncSetup); diff --git a/plugins/deviceplugins/mock/httpdaemon.cpp b/plugins/deviceplugins/mock/httpdaemon.cpp index d9c4bfeb..e19666e8 100644 --- a/plugins/deviceplugins/mock/httpdaemon.cpp +++ b/plugins/deviceplugins/mock/httpdaemon.cpp @@ -143,10 +143,10 @@ QString HttpDaemon::generateWebPage() body.append("

States

"); body.append(""); - for (int i = 0; i < deviceClass.states().count(); ++i) { + for (int i = 0; i < deviceClass.stateTypes().count(); ++i) { body.append(""); body.append(""); - const StateType &stateType = deviceClass.states().at(i); + const StateType &stateType = deviceClass.stateTypes().at(i); body.append(""); body.append(QString("").arg(stateType.id().toString()).arg(m_device->states().at(i).value().toString())); body.append(""); @@ -159,16 +159,21 @@ QString HttpDaemon::generateWebPage() body.append("

Events

"); body.append("
" + stateType.name() + "
"); - for (int i = 0; i < deviceClass.events().count(); ++i) { - const EventType &eventType = deviceClass.events().at(i); + for (int i = 0; i < deviceClass.eventTypes().count(); ++i) { + qDebug() << "adding eventType" << deviceClass.eventTypes().at(i).name(); + const EventType &eventType = deviceClass.eventTypes().at(i); body.append(QString( "" "" "" - "" + "" "" "" - ).arg(eventType.name()).arg(eventType.id().toString())); + ); } body.append("
%1").arg(eventType.name()).arg(eventType.id().toString())); + if (!eventType.name().endsWith(" changed")) { + body.append(""); + } + body.append("
"); @@ -181,7 +186,7 @@ QString HttpDaemon::generateWebPage() ActionTypeId actionTypeId = ActionTypeId(m_actionList.at(i).first); QDateTime timestamp = m_actionList.at(i).second; QString actionName; - foreach (const ActionType &at, deviceClass.actions()) { + foreach (const ActionType &at, deviceClass.actionTypes()) { if (at.id() == actionTypeId) { actionName = at.name(); break; diff --git a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp index 860a2a51..5c08e16e 100644 --- a/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp +++ b/plugins/deviceplugins/openweathermap/devicepluginopenweathermap.cpp @@ -326,7 +326,7 @@ QList DevicePluginOpenweathermap::supportedDevices() const params.append(locationParam); //Location is all we need for discovery. - deviceClassOpenweathermap.setDiscoveryParams(params); + deviceClassOpenweathermap.setDiscoveryParamTypes(params); ParamType countryParam("country", QVariant::String); params.append(countryParam); @@ -334,7 +334,7 @@ QList DevicePluginOpenweathermap::supportedDevices() const ParamType idParam("id", QVariant::String); params.append(idParam); - deviceClassOpenweathermap.setParams(params); + deviceClassOpenweathermap.setParamTypes(params); // Actions QList weatherActions; @@ -417,7 +417,7 @@ QList DevicePluginOpenweathermap::supportedDevices() const weatherStates.append(sunriseState); deviceClassOpenweathermap.setActions(weatherActions); - deviceClassOpenweathermap.setStates(weatherStates); + deviceClassOpenweathermap.setStateTypes(weatherStates); ret.append(deviceClassOpenweathermap); return ret; diff --git a/plugins/deviceplugins/wakeonlan/devicepluginwakeonlan.cpp b/plugins/deviceplugins/wakeonlan/devicepluginwakeonlan.cpp index 0c253cb9..1ddb7f77 100644 --- a/plugins/deviceplugins/wakeonlan/devicepluginwakeonlan.cpp +++ b/plugins/deviceplugins/wakeonlan/devicepluginwakeonlan.cpp @@ -158,7 +158,7 @@ QList DevicePluginWakeOnLan::supportedDevices() const wolAction.setName("wakeup"); wolActions.append(wolAction); - deviceClassWakeOnLan.setParams(wolParams); + deviceClassWakeOnLan.setParamTypes(wolParams); deviceClassWakeOnLan.setActions(wolActions); ret.append(deviceClassWakeOnLan); diff --git a/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp b/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp index c44743c2..a7781484 100644 --- a/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp +++ b/plugins/deviceplugins/wifidetector/devicepluginwifidetector.cpp @@ -52,7 +52,7 @@ QList DevicePluginWifiDetector::supportedDevices() const ParamType macParam("mac", QVariant::String); detectorParams.append(macParam); - deviceClassWifiDetector.setParams(detectorParams); + deviceClassWifiDetector.setParamTypes(detectorParams); QList detectorStates; @@ -62,7 +62,7 @@ QList DevicePluginWifiDetector::supportedDevices() const inRangeState.setDefaultValue(false); detectorStates.append(inRangeState); - deviceClassWifiDetector.setStates(detectorStates); + deviceClassWifiDetector.setStateTypes(detectorStates); ret.append(deviceClassWifiDetector); diff --git a/server/guhcore.cpp b/server/guhcore.cpp index 21aeb279..32271071 100644 --- a/server/guhcore.cpp +++ b/server/guhcore.cpp @@ -101,6 +101,10 @@ GuhCore::GuhCore(QObject *parent) : here will be evaluated by the \l{RuleEngine} and the according \l{Action}{Actions} are executed.*/ void GuhCore::gotEvent(const Event &event) { + // first inform other things about it. + emit eventTriggered(event); + + // Now execute all the associated rules foreach (const Action &action, m_ruleEngine->evaluateEvent(event)) { qDebug() << "executing action" << action.actionTypeId(); QPair status = m_deviceManager->executeAction(action); diff --git a/server/guhcore.h b/server/guhcore.h index 7fbc9923..56d67aff 100644 --- a/server/guhcore.h +++ b/server/guhcore.h @@ -42,6 +42,9 @@ public: DeviceManager* deviceManager() const; RuleEngine *ruleEngine() const; +signals: + void eventTriggered(const Event &event); + private: explicit GuhCore(QObject *parent = 0); static GuhCore *s_instance; diff --git a/server/jsonrpc/actionhandler.cpp b/server/jsonrpc/actionhandler.cpp index 777e01b5..8b18b43f 100644 --- a/server/jsonrpc/actionhandler.cpp +++ b/server/jsonrpc/actionhandler.cpp @@ -82,7 +82,7 @@ JsonReply *ActionHandler::GetActionType(const QVariantMap ¶ms) const { ActionTypeId actionTypeId(params.value("actionTypeId").toString()); foreach (const DeviceClass &deviceClass, GuhCore::instance()->deviceManager()->supportedDevices()) { - foreach (const ActionType &actionType, deviceClass.actions()) { + foreach (const ActionType &actionType, deviceClass.actionTypes()) { if (actionType.id() == actionTypeId) { QVariantMap data; data.insert("success", true); diff --git a/server/jsonrpc/devicehandler.cpp b/server/jsonrpc/devicehandler.cpp index 17a233f8..d1a0d8ee 100644 --- a/server/jsonrpc/devicehandler.cpp +++ b/server/jsonrpc/devicehandler.cpp @@ -391,7 +391,7 @@ JsonReply* DeviceHandler::GetEventTypes(const QVariantMap ¶ms) const QVariantList eventList; DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(DeviceClassId(params.value("deviceClassId").toString())); - foreach (const EventType &eventType, deviceClass.events()) { + foreach (const EventType &eventType, deviceClass.eventTypes()) { eventList.append(JsonTypes::packEventType(eventType)); } returns.insert("eventTypes", eventList); @@ -404,7 +404,7 @@ JsonReply* DeviceHandler::GetActionTypes(const QVariantMap ¶ms) const QVariantList actionList; DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(DeviceClassId(params.value("deviceClassId").toString())); - foreach (const ActionType &actionType, deviceClass.actions()) { + foreach (const ActionType &actionType, deviceClass.actionTypes()) { actionList.append(JsonTypes::packActionType(actionType)); } returns.insert("actionTypes", actionList); @@ -417,7 +417,7 @@ JsonReply* DeviceHandler::GetStateTypes(const QVariantMap ¶ms) const QVariantList stateList; DeviceClass deviceClass = GuhCore::instance()->deviceManager()->findDeviceClass(DeviceClassId(params.value("deviceClassId").toString())); - foreach (const StateType &stateType, deviceClass.states()) { + foreach (const StateType &stateType, deviceClass.stateTypes()) { stateList.append(JsonTypes::packStateType(stateType)); } returns.insert("stateTypes", stateList); diff --git a/server/jsonrpc/eventhandler.cpp b/server/jsonrpc/eventhandler.cpp new file mode 100644 index 00000000..193862de --- /dev/null +++ b/server/jsonrpc/eventhandler.cpp @@ -0,0 +1,48 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh 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 guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "eventhandler.h" +#include "guhcore.h" + +EventHandler::EventHandler(QObject *parent) : + JsonHandler(parent) +{ + QVariantMap params; + QVariantMap returns; + + // Notifications + params.clear(); returns.clear(); + setDescription("EventTriggered", "Emitted whenever an Event is triggered."); + params.insert("event", JsonTypes::eventRef()); + setParams("EventTriggered", params); + + connect(GuhCore::instance(), &GuhCore::eventTriggered, this, &EventHandler::eventTriggered); +} + +QString EventHandler::name() const +{ + return "Events"; +} + +void EventHandler::eventTriggered(const Event &event) +{ + QVariantMap params; + params.insert("event", JsonTypes::packEvent(event)); + emit EventTriggered(params); +} + diff --git a/server/jsonrpc/eventhandler.h b/server/jsonrpc/eventhandler.h new file mode 100644 index 00000000..d0d52b1e --- /dev/null +++ b/server/jsonrpc/eventhandler.h @@ -0,0 +1,38 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * * + * This file is part of guh. * + * * + * Guh is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, version 2 of the License. * + * * + * Guh 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 guh. If not, see . * + * * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef EVENTHANDLER_H +#define EVENTHANDLER_H + +#include "jsonhandler.h" + +class EventHandler : public JsonHandler +{ + Q_OBJECT +public: + explicit EventHandler(QObject *parent = 0); + QString name() const override; + +signals: + void EventTriggered(const QVariantMap ¶ms); + +private slots: + void eventTriggered(const Event &event); +}; + +#endif // EVENTHANDLER_H diff --git a/server/jsonrpc/jsonrpcserver.cpp b/server/jsonrpc/jsonrpcserver.cpp index 5aa2a0ba..ecf753ba 100644 --- a/server/jsonrpc/jsonrpcserver.cpp +++ b/server/jsonrpc/jsonrpcserver.cpp @@ -37,6 +37,7 @@ #include "devicehandler.h" #include "actionhandler.h" #include "ruleshandler.h" +#include "eventhandler.h" #include #include @@ -138,6 +139,7 @@ void JsonRPCServer::setup() registerHandler(new DeviceHandler(this)); registerHandler(new ActionHandler(this)); registerHandler(new RulesHandler(this)); + registerHandler(new EventHandler(this)); } void JsonRPCServer::processData(const QUuid &clientId, const QByteArray &jsonData) diff --git a/server/jsonrpc/jsontypes.cpp b/server/jsonrpc/jsontypes.cpp index cb009678..6aea8a66 100644 --- a/server/jsonrpc/jsontypes.cpp +++ b/server/jsonrpc/jsontypes.cpp @@ -191,7 +191,11 @@ QVariantMap JsonTypes::packEventType(const EventType &eventType) QVariantMap variant; variant.insert("id", eventType.id()); variant.insert("name", eventType.name()); - variant.insert("paramTypes", eventType.parameters()); + QVariantList paramTypes; + foreach (const ParamType ¶mType, eventType.parameters()) { + paramTypes.append(packParamType(paramType)); + } + variant.insert("paramTypes", paramTypes); return variant; } @@ -305,23 +309,23 @@ QVariantMap JsonTypes::packDeviceClass(const DeviceClass &deviceClass) variant.insert("id", deviceClass.id()); variant.insert("vendorId", deviceClass.vendorId()); QVariantList stateTypes; - foreach (const StateType &stateType, deviceClass.states()) { + foreach (const StateType &stateType, deviceClass.stateTypes()) { stateTypes.append(packStateType(stateType)); } QVariantList eventTypes; - foreach (const EventType &eventType, deviceClass.events()) { + foreach (const EventType &eventType, deviceClass.eventTypes()) { eventTypes.append(packEventType(eventType)); } QVariantList actionTypes; - foreach (const ActionType &actionType, deviceClass.actions()) { + foreach (const ActionType &actionType, deviceClass.actionTypes()) { actionTypes.append(packActionType(actionType)); } QVariantList paramTypes; - foreach (const ParamType ¶mType, deviceClass.params()) { + foreach (const ParamType ¶mType, deviceClass.paramTypes()) { paramTypes.append(packParamType(paramType)); } QVariantList discoveryParamTypes; - foreach (const ParamType ¶mType, deviceClass.discoveryParams()) { + foreach (const ParamType ¶mType, deviceClass.discoveryParamTypes()) { discoveryParamTypes.append(packParamType(paramType)); } diff --git a/server/ruleengine.cpp b/server/ruleengine.cpp index b15a2aea..3485a099 100644 --- a/server/ruleengine.cpp +++ b/server/ruleengine.cpp @@ -190,7 +190,7 @@ RuleEngine::RuleError RuleEngine::addRule(const EventDescriptor &eventDescriptor qDebug() << "found deviceClass" << deviceClass.name(); bool eventTypeFound = false; - foreach (const EventType &eventType, deviceClass.events()) { + foreach (const EventType &eventType, deviceClass.eventTypes()) { if (eventType.id() == eventDescriptor.eventTypeId()) { eventTypeFound = true; } diff --git a/server/server.pri b/server/server.pri index bd1d286d..7a7f84e2 100644 --- a/server/server.pri +++ b/server/server.pri @@ -8,7 +8,8 @@ SOURCES += $$top_srcdir/server/guhcore.cpp \ $$top_srcdir/server/jsonrpc/jsontypes.cpp \ $$top_srcdir/server/jsonrpc/ruleshandler.cpp \ $$top_srcdir/server/jsonrpc/actionhandler.cpp \ - $$top_srcdir/server/stateevaluator.cpp + $$top_srcdir/server/jsonrpc/eventhandler.cpp \ + $$top_srcdir/server/stateevaluator.cpp \ HEADERS += $$top_srcdir/server/guhcore.h \ $$top_srcdir/server/tcpserver.h \ @@ -20,4 +21,5 @@ HEADERS += $$top_srcdir/server/guhcore.h \ $$top_srcdir/server/jsonrpc/jsontypes.h \ $$top_srcdir/server/jsonrpc/ruleshandler.h \ $$top_srcdir/server/jsonrpc/actionhandler.h \ - $$top_srcdir/server/stateevaluator.h + $$top_srcdir/server/jsonrpc/eventhandler.h \ + $$top_srcdir/server/stateevaluator.h \ diff --git a/tests/auto/api.json b/tests/auto/api.json index 37cc53ee..8b6e91d2 100644 --- a/tests/auto/api.json +++ b/tests/auto/api.json @@ -1,4 +1,4 @@ -0.1.5 +0.1.6 { "methods": { "Actions.ExecuteAction": { @@ -253,6 +253,12 @@ "stateTypeId": "uuid", "variant": "value" } + }, + "Events.EventTriggered": { + "description": "Emitted whenever an Event is triggered.", + "params": { + "event": "$ref:Event" + } } }, "types": { diff --git a/tests/auto/devices/testdevices.cpp b/tests/auto/devices/testdevices.cpp index 433c592f..64cb5f84 100644 --- a/tests/auto/devices/testdevices.cpp +++ b/tests/auto/devices/testdevices.cpp @@ -383,7 +383,7 @@ void TestDevices::getEventTypes_data() QTest::addColumn("deviceClassId"); QTest::addColumn("resultCount"); - QTest::newRow("valid deviceclass") << mockDeviceClassId << 2; + QTest::newRow("valid deviceclass") << mockDeviceClassId << 4; QTest::newRow("invalid deviceclass") << DeviceClassId("094f8024-5caa-48c1-ab6a-de486a92088f") << 0; } diff --git a/tests/auto/jsonrpc/testjsonrpc.cpp b/tests/auto/jsonrpc/testjsonrpc.cpp index 6067810d..7be5a306 100644 --- a/tests/auto/jsonrpc/testjsonrpc.cpp +++ b/tests/auto/jsonrpc/testjsonrpc.cpp @@ -210,7 +210,7 @@ void TestJSONRPC::stateChangeEmitsNotifications() // Lets wait for the notification clientSpy.wait(); - QCOMPARE(clientSpy.count(), 1); + QCOMPARE(clientSpy.count(), 2); // Make sure the notification contains all the stuff we expect QJsonDocument jsonDoc = QJsonDocument::fromJson(clientSpy.at(0).at(1).toByteArray()); @@ -218,6 +218,12 @@ void TestJSONRPC::stateChangeEmitsNotifications() QCOMPARE(jsonDoc.toVariant().toMap().value("params").toMap().value("stateTypeId").toUuid(), stateTypeId); QCOMPARE(jsonDoc.toVariant().toMap().value("params").toMap().value("value").toInt(), newVal); + // Make sure the notification contains all the stuff we expect + jsonDoc = QJsonDocument::fromJson(clientSpy.at(1).at(1).toByteArray()); + QCOMPARE(jsonDoc.toVariant().toMap().value("notification").toString(), QString("Events.EventTriggered")); + QCOMPARE(jsonDoc.toVariant().toMap().value("params").toMap().value("event").toMap().value("eventTypeId").toUuid(), stateTypeId); + QCOMPARE(jsonDoc.toVariant().toMap().value("params").toMap().value("event").toMap().value("params").toList().first().toMap().value("value").toInt(), newVal); + // Now turn off notifications params.clear(); params.insert("enabled", false);