Skip to main content

Build a SubNode Application

Use the WEDA SubNode SDK to turn equipment readings or application output into telemetry that WEDA can manage. Start with the included Modbus simulator, then configure a real source and package an image for deployment through WEDA Node.

WEDA SubNode SDK on GitHub provides the source, project templates, examples and detailed SDK documentation. The examples below use the repository's release/v1.1.0 branch.

Understand SubNode and WEDA Node​

A SubNode application reads its sources, processes the readings and sends telemetry through WEDA Node. WEDA Node carries the connection to WEDA Cloud. The SubNode has its own device identity in Cloud, separate from its parent WEDA Node.

Within the SDK, a SubNode can contain multiple Device objects, each with its own Sensors. These Device objects represent equipment or data sources inside your application; they are different from the SubNode's Cloud device record.

For example, the template in this guide contains one Modbus Device with a temperature Sensor. You first test its readings locally, then verify that its telemetry reaches the SubNode's DataStreams in Cloud.

Get the SDK and Prepare Your Environment​

Prepare the tools for the stage you are working on:

StageRequirements
Build and run locallyGit, .NET 10.0 SDK and a C# editor; access to restore the project's NuGet packages
Build a container imageDocker on the build machine
Publish an imageAccess to a container registry and an image architecture compatible with the target WEDA Node

The repository also includes a VS Code Dev Container with development tools and templates. The shell commands in this guide use Bash.

  1. Obtain the source:

    git clone --branch release/v1.1.0 https://github.com/Advantech-WEDA/WEDA-Sub-Node.git
    cd WEDA-Sub-Node
    dotnet --version
  2. Confirm that .NET SDK 10.0 is available. Keep the repository layout: the templates reference SDK projects under src/.

  3. Use templates/ for new projects, examples/ for existing integrations and the SDK documentation for configuration and extension details.

Install Project Templates​

From the repository root, install both templates:

dotnet new install ./templates/wedabuilder
dotnet new install ./templates/subnode
dotnet new list weda
Short nameDevelopment approach
wedabuilderBuilder pattern with host-managed lifecycle; use this for the walkthrough below
subnodeConsole-style application with explicit SubNode initialization and lifecycle control

Check the result: The template list includes both wedabuilder and subnode.

If you use bash scripts/install-templates.sh instead, note that it removes known older WEDA template registrations before installing the repository's templates.

Create and Run Your First Project​

  1. Create the project under apps/ inside the cloned repository:

    mkdir -p apps
    cd apps
    dotnet new wedabuilder -n MyFirstSubNode
    cd MyFirstSubNode
    dotnet run
  2. Watch the terminal for the simulator starting and temperature_sensor readings. The generated configuration uses 127.0.0.1:5020 for the Modbus simulator.

  3. Press Ctrl+C to stop the application before changing its configuration.

Note: This first run is local

The template starts a Modbus simulator and calls UseMockCloud(). MockCloud simulates the Cloud service locally; this run does not create a device or send telemetry to your WEDA Cloud environment.

Check the result: You can read changing simulated temperature values without physical equipment or a WEDA Node connection.

Keep the generated project under apps/MyFirstSubNode/. Its project references use ../../src/; moving only the application directory breaks those references.

Connect Sensors and Configure Data​

The generated files separate the integration settings:

FileWhat you configure
Program.csDevice registration, hosting and MockCloud selection
MyFirstDevice.csThe Modbus Device class and handling of received readings
devicecfg.jsonSubNode metadata, source connection, Sensors and reporting
appsettings.jsonLogging and the built-in Modbus simulator
systemcfg.jsonThe connection and authentication settings for WEDA Node

For the temperature example:

  1. In devicecfg.json, set SubNode.Name to MyFirstSubNode. Keep the DeviceConfigs.MyFirstDevice key aligned with AddDevice<MyFirstDevice>("MyFirstDevice") in Program.cs.

  2. Review the existing Sensor in DeviceConfigs.MyFirstDevice.Sensors. It reads two holding registers as a Float32 and declares the resulting telemetry as double:

    {
    "Name": "temperature_sensor",
    "SensorGroup": "TEMP",
    "SensorInfo": {
    "DisplayName": "Temperature Sensor",
    "Description": "Main temperature reading",
    "Schema": "double"
    },
    "Parameters": {
    "RegisterType": "HoldingRegister",
    "RegisterAddress": 0,
    "RegisterCount": 2,
    "DataType": "Float32"
    },
    "Report": {
    "Enabled": true,
    "Interval": 1000,
    "Unit": "celsius"
    }
    }

    Parameters.DataType describes how to interpret the Modbus registers. SensorInfo.Schema describes the telemetry value. Report.Interval is in milliseconds. Keep the Sensor name stable when continuing the same integration.

  3. For real equipment, change DeviceCommunication.Host, Port, Properties.SlaveId and the Sensor register settings to match its register map. Remove the simulator hosted-service registration from Program.cs when the simulator is no longer needed.

  4. Run the application again and compare its readings with the source.

The SDK provides integrations for Modbus TCP/RTU, MQTT and HTTP, and supports custom Device implementations. Select a matching Device class or repository example; the Modbus fields above do not configure a different protocol.

For optional processing, configure Report.TransformPipeline for operations such as calibration or unit conversion, followed by Report.DspPipeline for filtering. See the pipeline configuration guide for processor settings. Image and binary integrations have different value and schema requirements; use the image-sensor example when developing those sources.

Check the result: The application reads the intended source with the expected value type, unit and reporting settings before you package the application.

Implement Custom Commands​

Your application can implement actions that a Cloud application invokes through WEDA Node. Define the command keyword and parameters, validate the request, handle the operation and return a structured result.

Note: The custom-command example uses SDK v1.2 RC

The public Custom Command Handler Example is on feature/v1.2.0-rc. It is an optional reference, separate from the release/v1.1.0 template walkthrough above. Use the example with its own SDK checkout; do not copy its files into the earlier project and assume compatibility.

Start with sensor.read, which returns the latest available reading for a named Sensor. It demonstrates the application side of the Cloud command used in Remote Commands.

ConcernFile under examples/feature-custom-commands/
Keyword and parametersCommands/SensorRead/Models/SensorReadCommand.cs: [DeviceCmd("sensor.read")], optional deviceName, required sensorName
Request validationCommands/SensorRead/SensorReadCommandValidator.cs
ExecutionCommands/SensorRead/SensorReadCommandHandler.cs
Typed resultCommands/SensorRead/Models/SensorReadResult.cs
Local test dispatchServices/CommandDemoService.cs

To study it locally:

  1. Obtain a separate checkout:

    git clone --branch feature/v1.2.0-rc https://github.com/Advantech-WEDA/WEDA-Sub-Node.git WEDA-Sub-Node-commands
    cd WEDA-Sub-Node-commands/examples/feature-custom-commands
  2. In that example's Program.cs, explicitly select MockCloud for an offline test:

    var builder = WedaApplication.CreateDefaultBuilder(args)
    .UseMockCloud();

    The current example's source defaults to a real Node connection. Keep its simulator and CommandDemoService registrations for this local test.

  3. Run dotnet run. Inspect the demo command outcomes and the returned Sensor value, timestamp and unit. The demo service also exercises tag.set and props.get, which illustrate typed map parameters and results.

  4. When adapting the example, implement your own handler and validation. The Host discovers handlers in the application assembly. Before production packaging, remove the local demo dispatcher and UseMockCloud().

Check the result: Local dispatch reaches the intended handler and returns a result. This checks the SDK command implementation, not the Cloud transport or the Cloud command catalog. Use the deployment guide below for that verification.

The README shows a device-message envelope using deviceCmd, timeout and respTopic. A Cloud caller uses the public REST contract, including deviceCommand and parameters; it does not POST that device envelope.

Package an Image for WEDA Deployment​

  1. Prepare the application for a real Node connection. In the main walkthrough's Program.cs, remove .UseMockCloud():

    var builder = WedaApplication.CreateDefaultBuilder(args);

    Keep the simulator only if you intend to deploy the simulated-temperature demonstration. Remove it when using your real source. Connection settings are supplied at deployment time in systemcfg.json.

  2. Keep only placeholder credentials in configuration files included in the build. The generated Dockerfile copies the source tree and publishes the application's JSON files. Prepare real connection credentials separately on the target device.

  3. From the repository root, build and publish an image. Replace the illustrative registry host, repository and tag with your own:

    SUBNODE_IMAGE='registry.example.com/weda/my-first-subnode:1.0.0'
    docker build -f apps/MyFirstSubNode/Dockerfile -t "$SUBNODE_IMAGE" .
    docker login registry.example.com
    docker push "$SUBNODE_IMAGE"

    The build context includes src/ and shared build files. Build for the target device's CPU architecture; a successful build on your workstation does not establish device compatibility.

  4. Prepare the generated configuration files and an image-based Compose definition using the next guide's example. Replace the template's build: section with the published image: reference.

Check the result: You have a versioned image in the registry, the application configuration files and a Compose definition referencing that image. Building or publishing the image does not create a WEDA deployment.

Continue with Deploy a SubNode Application with WEDA to prepare the target Node, deploy the Stack and check the container and SubNode separately.

References for Further Integration​

Choose the reference that matches your next task:

TaskOfficial SDK reference
Check Sensor fields and protocol settingsSensor Configuration Reference (v1.1.0)
Combine multiple sources in one SubNodeSubNode Hierarchy (v1.1.0)
Start from an existing Docker-based integrationSI Integration Guide (v1.1.0)
Report an AI container's HTTP or MQTT outputEdge AI Container Integration Recipe (v1.1.0)

The Edge AI recipe explains data-source and parser patterns. Adapt its code and payload mapping to your SDK version and application; adding arbitrary JSON alone does not implement a new protocol parser.

Constraints and Troubleshooting​

For image or binary sources, account for Base64 expansion: the SDK's default MIME validator checks an encoded string against 10,485,760 characters before decoding. For local recording, configure retention and capacity for your workload; older recordings can be removed by cleanup.

SymptomWhat to check
Template is not listedInstall from the cloned repository and check the .NET SDK version
SDK project cannot be foundKeep the application under apps/<project>/ so ../../src/ resolves
No local temperature readingsMatch the simulator/source endpoint, Device key, enabled Sensor and register settings