Third Party Plugins - Duet3D/DuetSoftwareFramework GitHub Wiki
Starting from DSF/DWC v3.3, third-party plugins are officially supported. In general, plugins may consist of three different components:
- DWC components
- SBC components (executables)
- SD files
Since Duets may operate in standalone mode, too, SBC components can be either optional or mandatory.
A guide for DWC plugin development is here: https://github.com/Duet3D/DuetWebControl/wiki/Third-Party-Plugins
For additional information on how to submit your plugin for hosting in the Duet3D plugin repository please see here: https://plugins.duet3d.com/guide/submission.html
Third-party plugins are generally bundled in a single ZIP file. The overall structure may look like this:
-
plugin.json
(required): This file holds general information about the plugin. See the following section for further details -
dsf/
directory: Contains executable and config files for the SBC portion (if applicable) -
dwc/
directory: Provides web files that are supposed to be accessible from Duet Web Control. It is symlinked or installed to 0:/www/<PluginName> -
sd/
directory: Holds files that are supposed to be installed into0:/
(the [virtual] SD card)
For security reasons a plugin bundle must not contain the following files:
- Filenames containing
..
sd/firmware/*
sd/sys/config.g
sd/sys/config-override.g
Every plugin must provide a plugin.json
in the root of its ZIP bundle. It may look like this:
{
"id": "DemoPluginId",
"name": "Demo Plugin",
"author": "Demo Author",
"version": "1.0.0",
"license": "LGPL-3.0-or-later",
"homepage": null,
"tags: ["demo"],
"dwcVersion": "3.3.0-b2",
"dwcDependencies": [],
"sbcRequired": false,
"sbcDsfVersion": null,
"sbcExecutable": null,
"sbcExecutableArguments": null,
"sbcExtraExecutables": [],
"sbcOutputRedirected": true,
"sbcPermissions": [],
"sbcPackageDependencies": [],
"sbcPythonDependencies": [],
"sbcPluginDependencies": [],
"rrfVersion": null,
"data": {}
}
where unused attributes may be omitted. Values for id
, name
, and author
must be always specified.
id
must be a simple string consisting only of alphanumeric characters and it must not exceed 32 characters. name
may consist only of alphanumeric characters, spaces, dashes (-
), and underscores (_
). It must not be empty and may not exceed 64 characters.
sbcPythonDependencies
has been introduced with DSF 3.4.
See the PluginManifest class documentation for further information about the provided fields.
In order to guarantee proper operation of your software components, it is mandatory to specify a version dependency per plugin component.
This means if you wish to provide a DWC plugin, you should specify at least the major.minor
version as the DWC version in the plugin manifest.
It is possible but not encouraged to specify only the major version as a dependency. For beta versions, specifying the full version string is recommended (e.g. 3.3.0-b2
).
If you intend to ship your plugin with SBC executables, you can flag if the SBC portion is required or optional (i.e. if it could operate in standalone mode too). To do this, specify the DSF version (sbcDsfVersion
) and set sbcRequired
to false
. If the SBC binary is mandatory for the plugin, set sbcRequired
to true
.
In case your plugin needs one or more plugins to be loaded first, you can specify the ID(s) of the required plugin(s) in dwcDependencies
. Note that circular dependencies are not supported.
Like for DWC, dependencies to other plugins may be defined for SBC components. Specify the ID(s) of required plugin(s) in sbcPluginDependencies
to ensure they are started before your plugin. In addition, package dependencies from apt
can be specified in the sbcPackageDependencies
list. These packages are attempted to be installed as part of the plugin installation routine.
Starting from DSF 3.4, third-party plugins may install Python dependencies. Each plugin will have its own Python virtual environment created where all the dependencies will be installed. Dependency versions can be specified using the pip versioning system. If no version is specified then the latest stable release on PyPi is used.
"sbcPythonDependencies": [
"dsf-python==3.4.5"
]
Starting from DSF 3.6, Git dependencies are also supported to allow installing a python package directly from github. This method can also be used to install private repos via ssh if the Pi has a valid sshkey.
"sbcPythonDependencies": [
"git+https://[email protected]/Duet3D/[email protected]#egg=dsf-python"
]
Starting from DSF 3.3, third-party plugins may be installed from the web interface. In order to maintain security, a user installing new plugins is asked for the required permissions before the plugin may be installed. This must be considered when designing a new external plugin.
This limitation does not effect external plugins running on the Pi (i.e. applications running outside
the /opt/dsf/plugins
directory as defined per PluginsDirectory
in config.json
). These programs
are automatically granted full permissions in DCS to retain backwards-compatibility.
DSF 3.2 introduces the following set of permissions:
Permission name | Description |
---|---|
commandExecution | Execute generic commands |
codeInterceptionRead | Read codes from the G/M/T-code streams but do not modify them |
codeInterceptionReadWrite | Read codes from the G/M/T-code streams and optionally modify them |
managePlugins | Install, load, unload, and uninstall plugins. Grants FS access to all third-party plugins too |
manageUserSessions | Add or remove user sessions |
objectModelRead | Read from the object model |
objectModelReadWrite | Read from and write to the object model |
registerHttpEndpoints | Register HTTP endpoints via Duet Web Server |
readFilaments | Read from 0:/filaments
|
writeFilaments | Write to 0:/filaments
|
readFirmware | Read from 0:/firmware
|
writeFirmware | Write to 0:/firmware
|
readGCodes | Read from 0:/gcodes
|
writeGCodes | Write to 0:/gcodes
|
readMacros | Read from 0:/macros
|
writeMacros | Write to 0:/macros
|
readSystem | Read from 0:/sys
|
writeSystem | Write to 0:/sys
|
readWeb | Read from 0:/www
|
writeWeb | Write to 0:/www
|
fileSystemAccess | Read and write to all files |
launchProcesses | Launch new processes |
networkAccess | Stand-alone network access |
webcamAccess | Access webcam devices |
gpioAccess | Access GPIO devices (/dev/gpiochip* ) and SPI/I2C devices (/dev/spidev* , /dev/i2c* ) |
superUser | Plugin runs as super-user (potentially dangerous, requires extra configuration steps) |
At least one of the following permissions must be defined in the plugin manifest in order to use the corresponding command in DCS:
Command name | Description | Required permissions |
---|---|---|
GetFileInfo | Parse G-Code file information | CommandExecution, FileSystemAccess, ReadGCodes |
ResolvePath | Resolve a virtual SD card path to a physical path | CommandExecution, FileSystemAccess |
Code | Execute an arbitrary G/M/T-code or interpret a comment | CommandExecution |
EvaluateExpression | Evaluate a meta command expression | CommandExecution |
Flush | Flush pending G/M/T-codes on a given channel | CommandExecution |
SimpleCode | Execute a text-based G/M/T-code or interpret a comment | CommandExecution |
WriteMessage | Write a generic message to the user and/or log file | CommandExecution, ObjectModelReadWrite |
AddHttpEndpoint | Register a new HTTP endpoint | RegisterHttpEndpoints |
RemoveHttpEndpoint | Unregister an existing HTTP endpoint | RegisterHttpEndpoints |
GetObjectModel | Query the full object model | ObjectModelRead, ObjectModelReadWrite |
LockObjectModel | Lock the object model for write access | ObjectModelReadWrite |
SetObjectModel | Set a single key in the object model (e.g. in Scanner) | ObjectModelReadWrite |
SyncObjectModel | Wait for the object model to be fully synchronized | CommandExecution, ObjectModelRead, ObjectModelReadWrite |
UnlockObjectModel | Unlock the object model again, see LockObjectModel | ObjectModelReadWrite |
InstallPlugin | Install or upgrade a plugin | ManagePlugins |
StartPlugin | Start a plugin | ManagePlugins |
StartPlugins | Start all the plugins | ManagePlugins |
SetPluginData | Set custom plugin data in the object model | ObjectModelReadWrite, ManagePlugins* |
StopPlugin | Stop a plugin (possibly including the one performing this command) | ManagePlugins |
StopPlugins | Stop all the plugins (possibly including the one performing this command) | ManagePlugins |
UninstallPlugin | Uninstall a plugin | ManagePlugins |
* Only needed to modify other data of other plugins
Every plugin is listed in the DSF object model in the plugins
namespace.
In this enumeration, plugins can provide shared information for other plugins, for
interfacing parts running in the web interface, or even for G-code expressions.
This kind of data may be modified using the HTTP
PATCH /machine/pluginData?key=<KEY>
request but only if the plugin does not provide an executable for the SBC.
If an executable wants to change plugin data, the usage of the SetPluginData
is advised.
In case the web interface portion needs to change something, create a new HTTP endpoint.
Whenever DCS is started, plugins that were started will be restarted. When DCS is shut down, it terminates (SIGTERM), and if that fails, forcefully kills (SIGKILL) plugin processes.
By default root plugins are not allowed (except for preinstalled plugins including DuetPiManagementPlugin).
To enable installation support for those plugins the setting RootPluginSupport
in /opt/dsf/conf/config.json
can be set from false
to true
.
In order to apply this option, DCS must be restarted either using a system reboot or via sudo systemctl restart duetcontrolserver
.
Note that enabling this option is a potential security hazard and is generally not encouraged.