From 45ecfa51b5e0a85982fde1c117b9c25ba0a7f632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Mon, 30 Jul 2018 16:33:12 +0200 Subject: [PATCH] Update simple button tutorial --- .../simplebutton/devicepluginsimplebutton.cpp | 19 ++- .../simplebutton/devicepluginsimplebutton.h | 1 - .../devicepluginsimplebutton.json | 14 +- doc/examples/simplebutton/extern-plugininfo.h | 22 +++ doc/examples/simplebutton/plugininfo.h | 44 ++++++ doc/tutorials/your-first-plugin.qdoc | 129 ++++++++++++++++++ 6 files changed, 224 insertions(+), 5 deletions(-) create mode 100644 doc/examples/simplebutton/extern-plugininfo.h create mode 100644 doc/examples/simplebutton/plugininfo.h diff --git a/doc/examples/simplebutton/devicepluginsimplebutton.cpp b/doc/examples/simplebutton/devicepluginsimplebutton.cpp index 1323f5c0..f427f2b6 100644 --- a/doc/examples/simplebutton/devicepluginsimplebutton.cpp +++ b/doc/examples/simplebutton/devicepluginsimplebutton.cpp @@ -63,5 +63,22 @@ DeviceManager::DeviceError DevicePluginSimpleButton::executeAction(Device *devic { qCDebug(dcSimpleButton()) << "Executing action for device" << device->name() << action.actionTypeId().toString() << action.params(); - return DeviceManager::DeviceErrorNoError; + // Check the device class + if (device->deviceClassId() == simplebuttonDeviceClassId) { + + // Check the action type + if (action.actionTypeId() == simplebuttonPressActionTypeId) { + + // Emit the pressed event on button press + qCDebug(dcSimpleButton()) << "Emit event pressed for simple button" << device->name(); + emitEvent(Event(simplebuttonPressedEventTypeId, device->id())); + return DeviceManager::DeviceErrorNoError; + } + + // Unhandled action type + return DeviceManager::DeviceErrorActionTypeNotFound; + } + + // Unhandled device type + return DeviceManager::DeviceErrorDeviceClassNotFound; } diff --git a/doc/examples/simplebutton/devicepluginsimplebutton.h b/doc/examples/simplebutton/devicepluginsimplebutton.h index a4093ee6..c509b843 100644 --- a/doc/examples/simplebutton/devicepluginsimplebutton.h +++ b/doc/examples/simplebutton/devicepluginsimplebutton.h @@ -33,7 +33,6 @@ class DevicePluginSimpleButton: public DevicePlugin Q_PLUGIN_METADATA(IID "io.nymea.DevicePlugin" FILE "devicepluginsimplebutton.json") Q_INTERFACES(DevicePlugin) - public: explicit DevicePluginSimpleButton(); diff --git a/doc/examples/simplebutton/devicepluginsimplebutton.json b/doc/examples/simplebutton/devicepluginsimplebutton.json index 3a6ce0a4..9184dec1 100644 --- a/doc/examples/simplebutton/devicepluginsimplebutton.json +++ b/doc/examples/simplebutton/devicepluginsimplebutton.json @@ -15,7 +15,7 @@ "deviceIcon": "None", "setupMethod": "JustAdd", "createMethods": ["User"], - "interfaces": [ ], + "interfaces": [ "simplebutton" ], "basicTags": [ ], "paramTypes": [ @@ -24,10 +24,18 @@ ], "actionTypes":[ - + { + "id": "64c4ced5-9a1a-4858-81dd-1b5c94dba495", + "name": "press", + "displayName": "press" + } ], "eventTypes":[ - + { + "id": "f9652210-9aed-4f38-8c19-2fd54f703fbe", + "name": "pressed", + "displayName": "button pressed" + } ] } ] diff --git a/doc/examples/simplebutton/extern-plugininfo.h b/doc/examples/simplebutton/extern-plugininfo.h new file mode 100644 index 00000000..e99ea3a9 --- /dev/null +++ b/doc/examples/simplebutton/extern-plugininfo.h @@ -0,0 +1,22 @@ +/* This file is generated by the nymea build system. Any changes to this file will + * be lost. + * + * If you want to change this file, edit the plugin's json file. + */ + +#ifndef EXTERNPLUGININFO_H +#define EXTERNPLUGININFO_H +#include "typeutils.h" +#include + +// Id definitions +extern PluginId pluginId; +extern VendorId guhVendorId; +extern DeviceClassId simplebuttonDeviceClassId; +extern ActionTypeId simplebuttonPressActionTypeId; +extern EventTypeId simplebuttonPressedEventTypeId; + +// Logging category definition +Q_DECLARE_LOGGING_CATEGORY(dcSimpleButton) + +#endif // EXTERNPLUGININFO_H diff --git a/doc/examples/simplebutton/plugininfo.h b/doc/examples/simplebutton/plugininfo.h new file mode 100644 index 00000000..c7926e25 --- /dev/null +++ b/doc/examples/simplebutton/plugininfo.h @@ -0,0 +1,44 @@ +/* This file is generated by the nymea build system. Any changes to this file will + * be lost. + * + * If you want to change this file, edit the plugin's json file. + */ + +#ifndef PLUGININFO_H +#define PLUGININFO_H + +#include +#include + +#include "typeutils.h" + +// Id definitions +PluginId pluginId = PluginId("28c7b102-3ac8-41f6-8dc0-f4787222a186"); +VendorId guhVendorId = VendorId("2062d64d-3232-433c-88bc-0d33c0ba2ba6"); +DeviceClassId simplebuttonDeviceClassId = DeviceClassId("c16ba02d-c982-4b45-8ca2-1945d94d8e66"); +ActionTypeId simplebuttonPressActionTypeId = ActionTypeId("64c4ced5-9a1a-4858-81dd-1b5c94dba495"); +EventTypeId simplebuttonPressedEventTypeId = EventTypeId("f9652210-9aed-4f38-8c19-2fd54f703fbe"); + +// Logging category +Q_DECLARE_LOGGING_CATEGORY(dcSimpleButton) +Q_LOGGING_CATEGORY(dcSimpleButton, "SimpleButton") + +// Translation strings +const QString translations[] { + //: The name of the plugin SimpleButton (28c7b102-3ac8-41f6-8dc0-f4787222a186) + QT_TRANSLATE_NOOP("SimpleButton", "Simple button"), + + //: The name of the vendor (2062d64d-3232-433c-88bc-0d33c0ba2ba6) + QT_TRANSLATE_NOOP("SimpleButton", "nymea"), + + //: The name of the DeviceClass (c16ba02d-c982-4b45-8ca2-1945d94d8e66) + QT_TRANSLATE_NOOP("SimpleButton", "Simple button"), + + //: The name of the ActionType 64c4ced5-9a1a-4858-81dd-1b5c94dba495 of deviceClass simplebutton + QT_TRANSLATE_NOOP("SimpleButton", "press"), + + //: The name of the EventType f9652210-9aed-4f38-8c19-2fd54f703fbe of deviceClass simplebutton + QT_TRANSLATE_NOOP("SimpleButton", "button pressed") +}; + +#endif // PLUGININFO_H diff --git a/doc/tutorials/your-first-plugin.qdoc b/doc/tutorials/your-first-plugin.qdoc index 7d2cb784..fe854444 100644 --- a/doc/tutorials/your-first-plugin.qdoc +++ b/doc/tutorials/your-first-plugin.qdoc @@ -23,7 +23,136 @@ \section1 Define the plugin properties + In order to start with the development, you have to take a closer look at the \tt{devicepluginsimplebutton.json} file. + In this file you can update the definitions of the \l{DevicePlugin}, \l{Vendor} and \l{DeviceClass}. + The full documentation of this plugin definition file and the properties can be found in \l{The plugin JSON File} documentation. + + \quotefile simplebutton/devicepluginsimplebutton.json + + First you have to update the plugin, vendor and device class id in the id fields. The wizard initializes these uuids with + the default zero uuid. You can use the \tt {uuidgen} command to create a new uuid and copy paste it into the id section. + + \note You have to rebuild the whole plugin once you update the deviceplugin JSON file. + + + \section2 The plugin definition + As you can see in this example, the plugin name is called \tt{SimpleButton}, and will be displayed as \tt{Simple button} plugin + in the client applications. The name can also be translated. The name will be used to define the debug category for your plugin. + In this example the debug categorie will be defined as \tt{dcSimpleButton} and can be used like following: + + \code + qCDebug(dcSimpleButton()) << "This is a debug information."; + qCWarning(dcSimpleButton()) << "This is a debug warning."; + qCCritical(dcSimpleButton()) << "This is a critical debug warning."; + \endcode + + The resulting debug output will look like following if the category is enabled: + + \code + $ nymead -n -d SimpleButton + + ... + + I | SimpleButton: This is a debug information. + W | SimpleButton: This is a debug warning. + C | SimpleButton: This is a critical debug warning. + \endcode + + This makes it easy to enable / disable the debug output of your plugin. + + \section2 The device class definition + + The Vendor section has not changed, since this example was developed from the guh Vendor. + + In order to give this simple button the required action and event described in the beginning of this tutorial, + we have to define the appropriate types: + + \code + "actionTypes":[ + { + "id": "64c4ced5-9a1a-4858-81dd-1b5c94dba495", + "name": "press", + "displayName": "press" + } + ], + \endcode + + This is the most simple action you can create. The \tt{name} property definies how the action will be called in the system. + The \tt{displayName} definies the string how the action will be displayed to the user and in the client applications. + + \code + "eventTypes":[ + { + "id": "f9652210-9aed-4f38-8c19-2fd54f703fbe", + "name": "pressed", + "displayName": "button pressed" + } + ] + \endcode + + This is the most simple event you can create. The \tt{name} property definies how the event will be called in the system. + The \tt{displayName} definies the string how the event will be displayed to the user and in the client applications. + + As you may have noticed, this example represents already an \l{Interfaces for DeviceClasses}{interface}. The \l{simplebutton} interface offers + a template for general simple buttons which are able to emit a \tt{pressed} event. In order to make use of the interface + you simply add the interface to the list. + + \code + ... + + "interfaces": [ "simplebutton" ], + + ... + \endcode + + The server will verify if the required types for an interface match the template. This will be evaluated once the server loads the plugin. + + Once you updated the JSON file, you have to rebuild the whole plugin in order to trigger a rebuild of the the plugin information + include files. + + \section2 nymea-generateplugininfo + + Before the source code will be compiled, a precompiler called \tt {nymea-generateplugininfo} will be launched. This tool will + read the plugin JSON file and generate two header files for the plugin in the build directory. + + \section3 plugininfo.h + + As you can see here this file contains all uuid definitions and translation string generated from the plugin JSON file. This file + will regenerated every time you + \quotefile simplebutton/plugininfo.h + + \section3 extern-plugininfo.h + + \quotefile simplebutton/extern-plugininfo.h + + \section1 Implement the plugin + + In order to implement this simple action and emit the Event once the button will be pressed, you need to implement following code: + + \quotefromfile simplebutton/devicepluginsimplebutton.cpp + \skipto DeviceManager::DeviceError DevicePluginSimpleButton::executeAction + \printuntil }\n + + In this code section you can see the implementation of the \tt executeAction method for this example tutorial. The method + will be called from DeviceManager once an Action should be executed. First we have to check for which device class this action + is ment. The we have to check which action of this device class should be executed. In this example we have only one deviceclass and + one action. + + \code + emitEvent(Event(simplebuttonPressedEventTypeId, device->id())); + \endcode + + And finally, once the action \tt press gets called, the event \tt pressed will be emitted in the system. + + This event can be connected whithin a rule to execute whatever action you want. + + \section1 Test the plugin + + Now it's time to build you first plugin. In order to make sure all changes in you JSON file are up to date press the \tt{Rebuild all} instead + of only \tt {Build}. This will rerun the nymea-generateplugininfo tool and update the \tt plugininfo.h and \tt extern-plugininfo.h files. + + \note Comming soon! */