Skip to content

About this article

  • Audience: Integrators extending Ghost Protocol edge firmware with runtime features
  • Goal: Deploy, manage, and author plugins without rebuilding the core oakapp image
  • Type: How-to

Summary

The Ghost Protocol edge plugin system lets you install packaged features on a running shadow over MQTT or CLI. Plugins run as sidecar processes alongside the main daemon and publish events back to the fleet bus.

Prerequisites

  • A deployed shadow with MQTT connectivity to the Phantom proxy
  • Plugin archive hosted at an HTTPS URL you control
  • M8 plugin architecture for hardware accessory work

Architecture

Three components cooperate:

ComponentRole
PluginManagerDownloads, extracts, activates, and removes plugin packages; thread-safe lifecycle
MQTT clientReceives deploy/remove commands and publishes plugin responses and events
vms_cliOperator CLI for deploy and remove when MQTT ingress is not preferred

Plugins ship as .tar.gz archives containing an __init__.py module with required entry points.

Required plugin contract

python
def start(mqtt_client):
    """Called when the plugin is deployed. Use mqtt_client to publish events."""
    pass

def stop():
    """Called on removal. Release hardware and stop background threads."""
    pass

MQTT topics

DirectionTopicPurpose
SOC → Edgedevices/{device_id}/cmd/pluginsDeploy and remove commands
VMS → Edgedevices/{device_id}/plugins/{plugin_id}/commandActivate or deactivate an installed plugin
VMS → Edgeshadow/{device_id}/plugins/{plugin_id}/commandMirrored runtime command namespace
Edge → VMSdevices/{device_id}/plugins/{plugin_id}/statusRetained runtime state and hardware validation result
Edge → SOCdevices/{device_id}/responsesOperation results and errors
Edge → SOCdevices/{device_id}/eventsPlugin-generated telemetry and incidents

Device IDs use role labels (site-role-a, site-role-b) in public examples.

Deploy and remove

Publish to devices/{device_id}/cmd/plugins:

json
{ "cmd": "deploy", "feature": "m8_controller", "url": "https://<your-storage>/plugins/m8_controller.tar.gz" }
{ "cmd": "remove", "feature": "m8_controller" }

CLI from [repo-root]: python3 oak-vms-firmware/tools/vms_cli.py plugin --action deploy|remove --feature m8_controller [--url <url>]

Deploy downloads the archive, calls start(), and acknowledges on responses. Remove calls stop(), deletes files, and confirms.

Activate and deactivate an installed plugin

The Fleet Plugins panel uses runtime commands so an operator can stop and restart a plugin without deleting its package:

json
{ "action": "activate", "plugin_id": "nist_fr", "device_id": "shadow2" }
{ "action": "deactivate", "plugin_id": "nist_fr", "device_id": "shadow2" }

Publish these payloads to devices/{device_id}/plugins/{plugin_id}/command. The edge validates the topic, payload plugin ID, REQUIRED_HARDWARE, and PLUGIN_EDGE_ENABLE, then publishes a retained status on devices/{device_id}/plugins/{plugin_id}/status.

Hardware-aware plugins receive the already-open camera queue context; they must not create a second Edge AI device or graph. In particular, nist_fr is eligible only on Shadow 2 and taps the S2 RGB/depth/NN queues.

Author a new plugin

  1. Create plugins/your_plugin/__init__.py with start and stop.
  2. Package the directory: tar -czf your_plugin.tar.gz -C plugins/your_plugin .
  3. Upload the archive to object storage with HTTPS access.
  4. Deploy to a lab shadow before fleet-wide rollout.
  5. Run python3 test_plugin_system.py in [repo-root] to validate the manager contract.

Follow the decoupled service model: plugins must not initialize the Edge AI pipeline or claim the camera while the main VMS daemon is active. Subscribe to local MQTT telemetry or call the MCP server for detection metadata instead.

Example: M8 controller

The M8 plugin monitors GPIO, drives relays and LEDs, publishes events on devices/{device_id}/events, and accepts commands on cmd/m8. See M8 plugin architecture.

Security considerations

Plugins run with firmware privileges — validate sources, prefer signed artifact URLs, and monitor resource usage. Dependencies: requests (downloads); hardware plugins add gpiod (lab) or luxonis_u2if (M8 on Shadow device OS).

Next steps

Operator depth

Live plugin versions, deploy evidence, and hardware validation logs live in private operator handoff (not published).