Skip to content

Build a class container

Build a class container when Dataplicity should install and version an on-device publisher for a product line.

Software tab for the SiloSentry Monitor device class showing a level sensor application, tank simulator, and video generator
The Software tab groups the containers a product class can run and shows which version is shipping.

The image is optional. The local agent broker is not optional for class streams: application telemetry goes to the broker, and the agent delivers it to Dataplicity.

text
container -> local agent broker -> agent-authenticated delivery -> Dataplicity

This workflow requires a field-agent release that includes the local stream broker and class-software runtime. It does not replace the existing agent installation guidance for Remote Shell and Wormhole. Your organisation administrator can confirm availability for the target device class.

Security contract

Your image must:

  • publish only to the agent-local broker
  • use class stream binding identifiers
  • keep Dataplicity device and organisation credentials out of the image
  • tolerate broker or network unavailability without treating direct cloud upload as a fallback
  • run with the smallest device permissions required by the hardware adapter

The broker endpoint for supported field-agent releases is:

text
POST http://127.0.0.1:18765/v1/streams/{binding_id}

The example publisher client posts JSON to that URL with Content-Type: application/json. A numeric sample looks like:

json
{
  "sequence": 1,
  "timestamp_ms": 1710000000000,
  "storageProfile": "volatile",
  "body": { "value": 12.4 },
  "metadata": { "source": "example-sim" }
}

storageProfile is volatile or durable. Keep the released helper for timestamp handling and error behaviour. Do not infer this contract from a browser API or from the public Gateway API.

Start from a sample image

The safest construction path is to keep the released publisher helper and replace only the simulated source:

  1. Open the Device Class Software tab.
  2. Choose Add container, keep Use an example, and pick the simulator closest to your data.
  3. Open that container, choose Upload version, and use Download a practice .tar if you need a local archive to inspect.
  4. Obtain the matching example source supplied with that image.
  5. Keep its broker client and bounded publish loop.
  6. Replace the sine, fill/drain, or temperature generator with your hardware adapter or application data source.
  7. Keep stream IDs aligned with the class UI Components tab.
  8. Move thresholds and installation-specific values into supported environment overrides.

The sample images are simulators, not hardware drivers. A production adapter still needs its own tests, bounds checking, and device-permission review.

Design the publisher

Separate the image into three small responsibilities:

PartResponsibility
Hardware adapterRead a sensor, local service, file, socket, or application state
NormaliserValidate type, range, unit, and missing-data behaviour
Broker publisherSend the normalised sample to its class binding on loopback

Use a stable interval appropriate to the signal. Avoid retry loops that spin when the broker is unavailable. The agent owns cloud buffering and retry; your process should preserve local stability and resume publishing when the broker returns.

Configure streams before building

Declare the streams on the Device Class first. For each stream, record:

  • binding identifier
  • customer-facing name
  • value type
  • unit
  • expected update interval
  • stale-data behaviour

Use the same binding identifier in the publisher and the device-page widget. See Device class streams.

Configure the image

Prefer environment variables for values that vary by class deployment, such as a setpoint, capacity, warning threshold, or sampling interval. Validate them at process start and fail clearly when their ordering is unsafe.

Do not use environment variables for Dataplicity credentials. The field agent is the credential boundary.

Hardware access is release and deployment specific. Verify the class-software runtime exposes the required serial port, GPIO interface, socket, or file before selecting this pattern. Do not add privileged mode or arbitrary device mounts that are not offered by the class Software configuration. If the existing product process already owns the hardware, publish from that process to the same local broker where supported.

Export an OCI archive

The upload field is Container image (.tar). The archive is a built OCI image, not a source-code tarball. Build for the target hardware architecture:

bash
docker buildx build --platform linux/arm64 \
  -t my-product-publisher:0.1.0 \
  --provenance=false --sbom=false \
  --output type=oci,dest=my-product-publisher_0.1.0_oci.tar \
  .

Change linux/arm64 to the architecture supported by the class. The Software upload accepts OCI archives with .tar, .tar.gz, or .tgz suffixes.

Upload and release

  1. Open the Device Class Software tab.
  2. Create the container with Add containerCreate new, or select an existing one.
  3. Choose Upload version and upload the OCI archive.
  4. Choose Create firmware and pin the container version.
  5. Make current for a staging device, or Pin to tags.
  6. Wait for the device to pull and start the image.
  7. Confirm stream samples in the OEM device page.
  8. Confirm the same customer-safe widgets in the customer portal.
  9. Expand the rollout only after restart and offline-recovery tests pass.

Use the firmware workflow for image rollout. A Fleet job is a command fanout, not a substitute for software version, eligibility, and deployment results.

Troubleshooting

No image starts

  • Confirm the device runs a field-agent release with class-software support.
  • Confirm the image architecture matches the hardware.
  • Confirm firmware pins a version and targets the staging device.
  • Inspect the deployment result before uploading the same archive again.

Image runs but no stream appears

  • Confirm the class contains the exact binding identifier.
  • Confirm the process posts to loopback, not a cloud URL.
  • Confirm the broker is present in the field-agent release.
  • Confirm the widget uses the same class stream.
  • Check value validation and publish-loop errors inside the image.

Values stop while the device is offline

Do not add cloud credentials to the image. Let the agent buffer and retry. Confirm publishing resumes locally and verify recovery after the device reconnects.

Hardware is unavailable inside the image

Check the permissions and device interfaces offered by the class-software runtime. If they do not expose the required hardware safely, keep the hardware adapter in the existing device runtime and publish to the local broker from there where supported.