Third Party Plugins - Duet3D/DuetSoftwareFramework GitHub Wiki

Introduction

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.

DWC plugin development

A guide for DWC plugin development is here: https://github.com/Duet3D/DuetWebControl/wiki/Third-Party-Plugins

Duet3D plugin repository

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

ZIP File Structure

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 into 0:/ (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

Plugin Manifest

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.

Version Dependencies

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.

DWC Dependencies

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.

SBC Dependencies

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.

SBC Python Dependencies

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"
  ]

SBC Permissions

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.

List of Permissions

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)

Required Permissions for each Command

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

Shared Data

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.

Lifecycle

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.

Root Plugins

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.

⚠️ **GitHub.com Fallback** ⚠️