Analyzer Basics
Use an Analyzer when your application needs a value derived from existing device data. An Analyzer runs in WEDA Cloud, applies an expression or JavaScript script, and publishes the result to an output DataStream. You can then query that output like other DataStreams.
This walkthrough uses a SubNode reading already expressed in mA, with an illustrative calibration of 4–20 mA to 0–100 °C. It introduces the shared REST API lifecycle through a standalone Transfer Function.
Across these guides, the same field example develops into two JavaScript stages: convert the current to temperature, then combine it with another temperature to produce a Boolean indicator. The standalone destination here is separate from that chain.
For the requests below, use your deployment's API base URL, an access token authorized for the target Org, and the Org ID and Device ID. Replace route placeholders and the illustrative UUIDs with your actual resource IDs.
Choose an Analyzer Type
Choose the computation first:
| Type | Use it for | Inputs and outputs |
|---|---|---|
Transfer Function, type: TransferFunction | A single mathematical expression, such as unit conversion or scaling. | Exactly one input and one output. |
JavaScript Analyzer, type: JavaScript | Script logic, calculations across several readings, or several derived results. | One to ten inputs and one or more outputs. |
The following guides cover how data reaches the computation:
- Multi-Input Processing: Configure Data Assembly when several inputs arrive at different times.
- Multilayer Analyzer: Use a JavaScript Analyzer's output as another JavaScript Analyzer's input. Multilayer is a connection between Analyzers, not a third Analyzer type.
- End-to-End Scenario: Build the complete current-to-temperature-to-Boolean example with two JavaScript Analyzers.
JavaScript has execution and script-length limits. Review those limits when preparing a script; this page's single-input Transfer Function does not use JavaScript or a multi-input assembly policy.
Configure Inputs and Outputs
Prepare both DataStreams before creating the Analyzer. For this example, all resources belong to the same target device:
The input binding gives an existing DataStream a variable name for the calculation. The output binding selects an existing destination DataStream; the Analyzer creation request does not create that destination.
Example calibration: (current_mA - 4) * 100 / 16 maps 4 mA to 0 °C and 20 mA to 100 °C. Replace that scale with the sensor's actual calibration. Use the SubNode's Device ID, and confirm the reported number is mA rather than a raw ADC count.
-
Use List DataStreams to find the numeric current stream on the SubNode device, already reporting mA. Retain its
dataStreamIdand confirm it has a recent value. -
Create a separate, user-managed output with Create a DataStream:
POST /api/v1/orgs/{orgId}/devices/{deviceId}/data-streams
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
"dataStreamName": "temperature_tf",
"displayName": "Standalone converted temperature",
"unitDisplay": "°C",
"dataType": "double",
"recordToDataLake": true
} -
After 201 Created, retain the output's returned
dataStreamId. It is initially unbound.unitDisplaylabels the unit; the Analyzer expression performs the conversion.
The following IDs are illustrative. Replace both wherever they occur. temperature_tf is the standalone destination used in this page and Transfer Function; the JavaScript chain uses a different temperature_a destination:
| Resource | Example ID | Purpose |
|---|---|---|
| Existing current input, mA | a1111111-1111-4111-8111-111111111111 | Supplies values to the calculation. |
| New standalone temperature output, °C | c3333333-3333-4333-8333-333333333333 | Receives the calculated values. |
An output DataStream must not already have a data source. Do not select a stream supplied by a WEDA Node, WEDA SubNode, Custom Device or another Analyzer. An already assigned output causes 409 Conflict. Using the same DataStream as both input and output is rejected with 400 Bad Request.
Check the result: The input has a recent current reading in mA, and a different output definition exists with dataType: double and no assigned source. If you need help finding or preparing these resources, follow DataStreams.
Create an Analyzer
Use Create Analyzer. The request combines these roles:
| Field | What you provide |
|---|---|
name | A human-readable name, up to 256 characters. description is optional, up to 500 characters. |
type | The selected computation type. |
inputParameters | Each input's dataStreamId and its parameterName in the expression or script. The variable name does not have to equal the DataStream's name. |
config | expression for Transfer Function, or script for JavaScript. |
outputs | The destination DataStream IDs. JavaScript also maps the returned value and timestamp to its outputs. |
For this illustrative 4–20 mA conversion:
POST /api/v1/orgs/{orgId}/devices/{deviceId}/analyzers
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
"name": "Standalone analog conversion",
"description": "Convert 4–20 mA to 0–100 Celsius using a standalone expression",
"type": "TransferFunction",
"inputParameters": [
{
"parameterName": "analog_current",
"dataStreamId": "a1111111-1111-4111-8111-111111111111"
}
],
"config": {
"expression": "(analog_current - 4) * 100 / 16"
},
"outputs": [
{
"dataStreamId": "c3333333-3333-4333-8333-333333333333"
}
]
}
After 201 Created, retain analyzerId. The expression uses analog_current, exactly matching the declared parameterName.
An Analyzer is created disabled, with isEnabled: false. Change this state through the enable / disable action; do not put isEnabled in a create, PUT or PATCH request.
Read the saved definition with Get Analyzer:
GET /api/v1/orgs/{orgId}/devices/{deviceId}/analyzers/{analyzerId}
Authorization: Bearer YOUR_ACCESS_TOKEN
To find an existing Analyzer, use List Analyzers. It supports a name keyword, sorting, skipCount and maxResultCount; retain the chosen result's analyzerId.
Check the result: GET returns the intended type, expression, input and output IDs, with isEnabled: false. An empty output is expected until the Analyzer is enabled and receives input.
Enable and Check the Result
-
Call Enable / Disable Analyzer with
enable:POST /api/v1/orgs/{orgId}/devices/{deviceId}/analyzers/{analyzerId}:enable
Authorization: Bearer YOUR_ACCESS_TOKEN -
After 204 No Content, GET the Analyzer and check
isEnabled: true. Wait for a new reading from the input source; this example does not require a historical query or Data Resync. -
Query the output DataStream, not the Analyzer definition, with Get Latest Value:
GET /api/v1/orgs/{orgId}/devices/{deviceId}/data-streams/{outputDataStreamId}/values/latest
Authorization: Bearer YOUR_ACCESS_TOKENReplace
outputDataStreamIdwith the actual standalone temperature stream ID retained earlier. ReaddataObject.valueanddataObject.timestamp.
Check the result: An input of 12 mA produces 50 °C under this calibration. Confirm that the output timestamp corresponds to the reading you are checking; for a changing sensor, the latest input and latest output may represent different samples.
The action's 204 confirms the state change. It does not prove the calculation has produced a value. Multi-input Analyzers also prepare their input combination in the background. Always verify a new output reading.
If a value is missing or unexpected, start with these checks:
| Observation | Check |
|---|---|
isEnabled is false | Enable the Analyzer and read back its state. |
| Latest-value query returns 204 | No qualifying latest value is available. Check for a new input reading and confirm the output ID. |
| Output value or timestamp is unexpected | Compare matching input and output samples, the saved expression and bindings. |
| Enable / disable returns 409 | Read the current state; the Analyzer may already be in the requested state. |
Historical verification additionally requires recorded values. Use DataStreams value queries for latest, historical and aggregate query details.
Update or Delete an Analyzer
Disable before changing the definition or deleting it:
POST /api/v1/orgs/{orgId}/devices/{deviceId}/analyzers/{analyzerId}:disable
Authorization: Bearer YOUR_ACCESS_TOKEN
After 204, GET the Analyzer and confirm isEnabled: false. An update or delete while it remains enabled returns 409 Conflict.
Update selected fields with Partially Update Analyzer. For example, change only the description:
PATCH /api/v1/orgs/{orgId}/devices/{deviceId}/analyzers/{analyzerId}
Content-Type: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
{
"description": "Standalone converted temperature for the operator dashboard"
}
- PATCH: Omitted fields retain their values.
typeis not a PATCH field. - PUT: Replace the full editable definition, including required
name,type,inputParameters,configandoutputs. - After either update: GET the saved definition. Re-enable it when ready, then verify a new output reading again.
Delete an Analyzer you no longer need with Delete Analyzer, keeping it disabled:
DELETE /api/v1/orgs/{orgId}/devices/{deviceId}/analyzers/{analyzerId}
Authorization: Bearer YOUR_ACCESS_TOKEN
Check the result: After 204 No Content, GET for that Analyzer returns 404 Not Found. Managing its output DataStream is a separate task. Before reusing or removing that stream, inspect its current source and resolve any remaining dependencies.