Add plugin wizard tutorial and improve style sheet
@ -3,8 +3,8 @@
|
|||||||
\title All nymea Modules
|
\title All nymea Modules
|
||||||
|
|
||||||
\table 80%
|
\table 80%
|
||||||
\row \li \l{nymeaserver} \li The nymea server daemon implementation
|
\row \li \l{nymeaserver} \li The nymea server daemon implementation
|
||||||
\row \li \l{libnymea} \li Common data types and plugin interfaces
|
\row \li \l{libnymea} \li Common data types and plugin interfaces
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
\generatelist legalese-command
|
\generatelist legalese-command
|
||||||
|
|||||||
@ -34,6 +34,7 @@ exampledirs = examples/
|
|||||||
sourcedirs = ..
|
sourcedirs = ..
|
||||||
sources.fileextensions = "*.cpp *.qdoc"
|
sources.fileextensions = "*.cpp *.qdoc"
|
||||||
|
|
||||||
Cpp.ignoredirectives = DECLARE_TYPE \
|
Cpp.ignoredirectives = Q_DECLARE_METATYPE \
|
||||||
DECLARE_OBJECT
|
Q_ENUM \
|
||||||
|
Q_ENUMS \
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
TEMPLATE = subdirs
|
TEMPLATE = subdirs
|
||||||
CONFIG += no_docs_target
|
CONFIG += no_docs_target
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
template \
|
template \
|
||||||
|
|||||||
@ -126,7 +126,7 @@ def extractTypes(types):
|
|||||||
|
|
||||||
typesSorted = sorted(typesList)
|
typesSorted = sorted(typesList)
|
||||||
for type in typesSorted:
|
for type in typesSorted:
|
||||||
writeToFile('\section3 %s' % type)
|
writeToFile('\section2 %s' % type)
|
||||||
writeCodeSection(types[type])
|
writeCodeSection(types[type])
|
||||||
if isinstance(types[type], dict):
|
if isinstance(types[type], dict):
|
||||||
writeToFile(createReferenceLine(types[type]))
|
writeToFile(createReferenceLine(types[type]))
|
||||||
@ -139,11 +139,11 @@ def extractMethods(methods):
|
|||||||
|
|
||||||
methodsSorted = sorted(methodsList)
|
methodsSorted = sorted(methodsList)
|
||||||
for method in methodsSorted:
|
for method in methodsSorted:
|
||||||
writeToFile('\section3 %s' % method)
|
writeToFile('\section2 %s' % method)
|
||||||
writeToFile('%s' % methods[method]['description'])
|
writeToFile('%s' % methods[method]['description'])
|
||||||
writeToFile('\section4 Params')
|
writeToFile('Params')
|
||||||
writeCodeSection(methods[method]['params'])
|
writeCodeSection(methods[method]['params'])
|
||||||
writeToFile('\section4 Returns')
|
writeToFile('Returns')
|
||||||
writeCodeSection(methods[method]['returns'])
|
writeCodeSection(methods[method]['returns'])
|
||||||
writeToFile(createReferenceLine(methods[method]))
|
writeToFile(createReferenceLine(methods[method]))
|
||||||
|
|
||||||
@ -155,9 +155,9 @@ def extractNotifications(notifications):
|
|||||||
|
|
||||||
notificationsSorted = sorted(notificationsList)
|
notificationsSorted = sorted(notificationsList)
|
||||||
for notification in notificationsSorted:
|
for notification in notificationsSorted:
|
||||||
writeToFile('\section3 %s' % notification)
|
writeToFile('\section2 %s' % notification)
|
||||||
writeToFile('%s' % notifications[notification]['description'])
|
writeToFile('%s' % notifications[notification]['description'])
|
||||||
writeToFile('\section4 Params')
|
writeToFile('Params')
|
||||||
writeCodeSection(notifications[notification]['params'])
|
writeCodeSection(notifications[notification]['params'])
|
||||||
writeToFile(createReferenceLine(notifications[notification]))
|
writeToFile(createReferenceLine(notifications[notification]))
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ def writeDocumentationContent(apiVersion, apiJson):
|
|||||||
extractMethods(apiJson['methods'])
|
extractMethods(apiJson['methods'])
|
||||||
|
|
||||||
if 'notifications' in apiJson:
|
if 'notifications' in apiJson:
|
||||||
writeToFile("\section2 Notifications")
|
writeToFile("\section1 Notifications")
|
||||||
extractNotifications(apiJson['notifications'])
|
extractNotifications(apiJson['notifications'])
|
||||||
|
|
||||||
writeToFile("\section1 Full introspect")
|
writeToFile("\section1 Full introspect")
|
||||||
|
|||||||
BIN
doc/images/plugin-template-1.png
Normal file
|
After Width: | Height: | Size: 107 KiB |
BIN
doc/images/plugin-template-2.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
doc/images/plugin-template-3.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
doc/images/plugin-template-4.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
BIN
doc/images/plugin-template-5.png
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
doc/images/plugin-template-6.png
Normal file
|
After Width: | Height: | Size: 169 KiB |
BIN
doc/images/plugin-template-7.png
Normal file
|
After Width: | Height: | Size: 452 KiB |
BIN
doc/images/plugin-template-8.png
Normal file
|
After Width: | Height: | Size: 333 KiB |
35
doc/main.css
@ -58,7 +58,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ol, ul {
|
ol, ul {
|
||||||
list-style: none;
|
list-style: list-style-type:circle;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote, q {
|
blockquote, q {
|
||||||
@ -829,22 +829,49 @@ div.header + li {
|
|||||||
color: #676767;
|
color: #676767;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content .sidebar ul {
|
.content .sidebar ul li {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
|
list-style-type: circle;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
.content .sidebar .level2:before {
|
||||||
|
content: "#";
|
||||||
|
background-image: none;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
.content .sidebar .level1 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
list-style: "- ";
|
||||||
}
|
}
|
||||||
|
|
||||||
.content .sidebar .level2 {
|
.content .sidebar .level2 {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
margin-left: 1rem;
|
margin-left: 1.5rem;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
list-style-type: circle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content .sidebar .level3 {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-left: 2rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
list-style: "→ ";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
.content .sidebar .level2:before {
|
.content .sidebar .level2:before {
|
||||||
content: "-";
|
content: "-";
|
||||||
background-image: none;
|
background-image: none;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
.content .context {
|
.content .context {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
margin: 0 -120px 0 auto;
|
margin: 0 -120px 0 auto;
|
||||||
@ -869,7 +896,7 @@ div.header + li {
|
|||||||
.content ul li {
|
.content ul li {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-left: calc(1.5em + 10px);
|
padding-left: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content ul li::before {
|
.content ul li::before {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
\example template
|
\example template
|
||||||
\title Plugin wizard
|
\title 1. Plugin wizard
|
||||||
\ingroup tutorials
|
\ingroup tutorials
|
||||||
\brief Explanation of the Qt Creator plugin wizard template
|
\brief Explanation of the Qt Creator plugin wizard template
|
||||||
|
|
||||||
@ -9,6 +9,88 @@
|
|||||||
qt-creator wizard on our \l{https://github.com/guh/nymea-qtcreator-wizards}{github page}.
|
qt-creator wizard on our \l{https://github.com/guh/nymea-qtcreator-wizards}{github page}.
|
||||||
|
|
||||||
|
|
||||||
|
\section1 Create the plugin project
|
||||||
|
|
||||||
|
Once you have installed all packages required for development, you can open the Qt Creator and start a new project.
|
||||||
|
If you need help with the overall Qt Creator project creation, you can find more information
|
||||||
|
\l{http://doc.qt.io/qtcreator/creator-project-creating.html}{here}.
|
||||||
|
|
||||||
|
\section2 Choose template
|
||||||
|
In the template view cou can find now the nymea section. In that section you can find the template for a new plugin.
|
||||||
|
\image plugin-template-1.png Create a new plugin
|
||||||
|
|
||||||
|
|
||||||
|
\section2 Project location
|
||||||
|
Choose the project name and the path where the project should be located. As in this example the name is \e{template}
|
||||||
|
and will be used within the source code as refference. A good practice is to pick a general describing name like a vendor
|
||||||
|
or product/project name.
|
||||||
|
\image plugin-template-2.png Project location
|
||||||
|
|
||||||
|
\section2 Plugin details
|
||||||
|
In this section the plugin details can be defined.
|
||||||
|
|
||||||
|
In the first part you can find the c++ specific definitions:
|
||||||
|
\list
|
||||||
|
\li \b{Class name}: Enter the name of the main class for this device plugin.
|
||||||
|
The naming should be \tt{DevicePlugin\e{Name}} in camel case.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
In the second part you can find the json specific definitions:
|
||||||
|
\list
|
||||||
|
\li \b{Vendor name}: Enter the name of the \l{Vendor}.
|
||||||
|
\li \b{Device name}: Enter the name for the default device which will be created as template.
|
||||||
|
You can change this any time in the json file.
|
||||||
|
\li \b{Setup method}: Pick the desired setup method for the default device which will be created as template.
|
||||||
|
You can change this any time in the json file. You can find more information in the
|
||||||
|
\l{CreateMethods and SetupMethods} section.
|
||||||
|
\li \b{Create method}: Pick the desired create method for the default device which will be created as template.
|
||||||
|
You can change this any time in the json file.
|
||||||
|
\li \b{Icon}: Pick the desired icon for the default device which will be created as template.
|
||||||
|
You can change this any time in the json file.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
See also the \l{CreateMethods and SetupMethods} section.
|
||||||
|
|
||||||
|
\image plugin-template-3.png Plugin details
|
||||||
|
|
||||||
|
\section2 Developer information
|
||||||
|
Enter the name and email address of the developer for this plugin. These information will be used in the
|
||||||
|
copyright sections of the plugin. The copyright information are placed in the \tt{debian/copyright} file and in each
|
||||||
|
source code license header.
|
||||||
|
\image plugin-template-4.png Developer information
|
||||||
|
|
||||||
|
\section2 Kit selection
|
||||||
|
Pick the build kit for this project. The kit must match the version of the \tt{nymead} and \tt{libnymea1} built.
|
||||||
|
|
||||||
|
\note: You have to make sure you are using the \underline{same kit} as the nymea daemon and libraries use. If you have installed the
|
||||||
|
\underline{nymea library} and \underline{Qt libraries} from you default system package manager, you should probably go with the
|
||||||
|
default kit of your distribution.
|
||||||
|
|
||||||
|
\image plugin-template-5.png Kit selection
|
||||||
|
|
||||||
|
\section2 Project Management
|
||||||
|
Here you can select your prefered project management tool. If you choose git,
|
||||||
|
the default \tt{.gitignore} file will be added to the project.
|
||||||
|
|
||||||
|
\image plugin-template-6.png Project Management
|
||||||
|
|
||||||
|
\section2 Project tree
|
||||||
|
Once you finished the plugin wizard, you can start with the development of you plugin.
|
||||||
|
\image plugin-template-7.png Project tree
|
||||||
|
|
||||||
|
\section1 Walk trough
|
||||||
|
|
||||||
|
Starting with the new created project you can find following files in you project:
|
||||||
|
|
||||||
|
\section2 template.pro
|
||||||
|
|
||||||
|
\quotefile template/template.pro
|
||||||
|
|
||||||
|
\section2 deviceplugintemplate.json
|
||||||
|
|
||||||
|
Here you can find the device plugin interface describibg the vendors, devices and plugin information.
|
||||||
|
A detailed description of each section can be found in the \l{The plugin JSON File} section.
|
||||||
|
|
||||||
|
\quotefile template/deviceplugintemplate.json
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -35,7 +35,6 @@ class QtAvahiServicePrivate;
|
|||||||
class QtAvahiService : public QObject
|
class QtAvahiService : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_ENUMS(QtAvahiServiceState)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum QtAvahiServiceState {
|
enum QtAvahiServiceState {
|
||||||
@ -45,6 +44,7 @@ public:
|
|||||||
QtAvahiServiceStateCollision = 3,
|
QtAvahiServiceStateCollision = 3,
|
||||||
QtAvahiServiceStateFailure = 4
|
QtAvahiServiceStateFailure = 4
|
||||||
};
|
};
|
||||||
|
Q_ENUM(QtAvahiServiceState)
|
||||||
|
|
||||||
explicit QtAvahiService(QObject *parent = nullptr);
|
explicit QtAvahiService(QObject *parent = nullptr);
|
||||||
~QtAvahiService();
|
~QtAvahiService();
|
||||||
|
|||||||
@ -34,6 +34,7 @@
|
|||||||
\l{DevicePlugin}{device plugins}.
|
\l{DevicePlugin}{device plugins}.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*! \enum DeviceManager::DeviceError
|
/*! \enum DeviceManager::DeviceError
|
||||||
|
|
||||||
This enum type specifies the errors that can happen when working with \l{Device}{Devices}.
|
This enum type specifies the errors that can happen when working with \l{Device}{Devices}.
|
||||||
@ -101,6 +102,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Signals
|
// Signals
|
||||||
|
|
||||||
/*! \fn void DeviceManager::loaded();
|
/*! \fn void DeviceManager::loaded();
|
||||||
The DeviceManager will emit this signal when all \l{Device}{Devices} are loaded.
|
The DeviceManager will emit this signal when all \l{Device}{Devices} are loaded.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -50,8 +50,6 @@ class HardwareManager;
|
|||||||
class LIBNYMEA_EXPORT DeviceManager : public QObject
|
class LIBNYMEA_EXPORT DeviceManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_ENUMS(DeviceError)
|
|
||||||
Q_ENUMS(DeviceSetupStatus)
|
|
||||||
|
|
||||||
friend class DevicePlugin;
|
friend class DevicePlugin;
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,8 @@
|
|||||||
file is read only.
|
file is read only.
|
||||||
\value SettingsRoleDeviceStates
|
\value SettingsRoleDeviceStates
|
||||||
This role will create the \b{device-states.conf} file and is used to store the configured \l{Device} \l{State}{States}.
|
This role will create the \b{device-states.conf} file and is used to store the configured \l{Device} \l{State}{States}.
|
||||||
|
\value SettingsRoleTags
|
||||||
|
This role will create the \b{tags.conf} file and is used to store the \l{Tag}{Tags}.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -114,7 +114,7 @@ DeviceId DeviceDescriptor::parentDeviceId() const
|
|||||||
return m_parentDeviceId;
|
return m_parentDeviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sets the parent device Id for devices created from this DeviceDescriptor. */
|
/*! Sets the parent device Id \a parentDeviceId for devices created from this DeviceDescriptor. */
|
||||||
void DeviceDescriptor::setParentDeviceId(const DeviceId &parentDeviceId)
|
void DeviceDescriptor::setParentDeviceId(const DeviceId &parentDeviceId)
|
||||||
{
|
{
|
||||||
m_parentDeviceId = parentDeviceId;
|
m_parentDeviceId = parentDeviceId;
|
||||||
|
|||||||
@ -46,7 +46,7 @@ ParamDescriptor::ParamDescriptor(const ParamTypeId ¶mTypeId, const QVariant
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Constructs an ParamDescriptor describing an \l{Param} with the given \a paramTypeId and \a value.
|
/*! Constructs an ParamDescriptor describing an \l{Param} with the given \a paramName and \a value.
|
||||||
* The ValueOperator is by default ValueOperatorEquals. */
|
* The ValueOperator is by default ValueOperatorEquals. */
|
||||||
ParamDescriptor::ParamDescriptor(const QString ¶mName, const QVariant &value):
|
ParamDescriptor::ParamDescriptor(const QString ¶mName, const QVariant &value):
|
||||||
Param(ParamTypeId(), value),
|
Param(ParamTypeId(), value),
|
||||||
|
|||||||
@ -13,7 +13,7 @@ doc.depends = FORCE
|
|||||||
# Note: some how extraimages in qdocconf did not the trick
|
# Note: some how extraimages in qdocconf did not the trick
|
||||||
doc.commands += cd $$top_srcdir/libnymea/interfaces; ./generatedoc.sh;
|
doc.commands += cd $$top_srcdir/libnymea/interfaces; ./generatedoc.sh;
|
||||||
doc.commands += cd $$top_srcdir/doc; ./generate-api-qdoc.py;
|
doc.commands += cd $$top_srcdir/doc; ./generate-api-qdoc.py;
|
||||||
doc.commands += cd $$top_srcdir/doc; qdoc config.qdocconf; cp -r images/* html/images/; \
|
doc.commands += cd $$top_srcdir/doc; qdoc --highlighting config.qdocconf; cp -r images/* html/images/; \
|
||||||
cp -r favicons/* html/; cp -r $$top_srcdir/doc/html $$top_builddir/
|
cp -r favicons/* html/; cp -r $$top_srcdir/doc/html $$top_builddir/
|
||||||
|
|
||||||
licensecheck.commands = $$top_srcdir/tests/auto/checklicenseheaders.sh $$top_srcdir
|
licensecheck.commands = $$top_srcdir/tests/auto/checklicenseheaders.sh $$top_srcdir
|
||||||
|
|||||||