Transfer Function
Use a Transfer Function to turn one numeric reading into one calculated value. The expression runs in WEDA Cloud and sends its result to a separate output DataStream.
This guide develops the standalone analog conversion in Analyzer Basics: 4–20 mA represents 0–100 °C in this example. Reuse that existing configuration if you already created it.
When to Use a Transfer Function
A Transfer Function fits calculations such as:
- Unit conversion: Express a reading in another unit.
- Scaling: Turn a current reading into an engineering value using the sensor's calibration.
- Calibration: Add an offset or apply a correction factor to one reading.
TransferFunction requires exactly one input DataStream and one output DataStream. Choose a JavaScript Analyzer when you need multiple inputs or several results. Multilayer Analyzer currently supports JavaScript Analyzers only.
Configure the Input and Output
Prepare these resources on the SubNode device that owns the current stream:
| Item | Example setting | What it means |
|---|---|---|
| Input DataStream | analog_current, already reported in mA | Supplies the numeric current, rather than a raw ADC count. |
| Input variable | parameterName: analog_current | Gives that input the name used in the expression. |
| Computation type | type: TransferFunction | Selects expression-based calculation. |
| Output DataStream | temperature_tf, double, unit °C | Separate, unbound destination for this standalone example. |
The parameter name can differ from the stream's name. Binding uses dataStreamId; the expression uses parameterName. Changing a unit label alone does not convert a reading.
For the output binding:
- Set
outputs[0].dataStreamIdto the destination's ID. - Omit
valueJsonPath, or use$for the whole numeric result. A property path such as$.valueis not valid for a Transfer Function. - Omit
timeJsonPath. The output uses the triggering input's timestamp.
Use DataStreams to find the input and prepare the output. The Create Analyzer API provides the field reference.
Write the Expression
Put one mathematical expression in config.expression, referencing the declared input directly:
(analog_current - 4) * 100 / 16
Here, subtracting 4 removes the lower current offset; dividing by the 16 mA span and multiplying by 100 applies the example's temperature span. Use your actual sensor range when adapting it.
- Use the variable's exact spelling, including capitalization.
- Use arithmetic operators such as
+,-,*and/; parentheses make the intended grouping clear. - Write the calculation itself. Do not add JavaScript
return, readanalog_current.value, or put a script inconfig.expression. - Reference the declared input. A constant-only expression is rejected.
For example, renaming the parameter to reading requires the expression (reading - 4) * 100 / 16. Renaming only the DataStream does not rename that variable.
The expression applies the formula to the number it receives. Validate that the current is within your intended input range. The JavaScript version of this example explicitly skips non-numeric and out-of-range readings.
If you edit a saved Analyzer, disable it before changing its definition, then read back the expression and re-enable it when ready.
Example: Convert an Analog Input to Temperature
The following configuration excerpt shows the type-specific fields. Use the complete request in Analyzer Basics to create it. Replace these illustrative IDs with your own:
{
"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"
}
]
}
| Input, mA | Calculation | Output, °C |
|---|---|---|
| 4 | (4 - 4) * 100 / 16 | 0 |
| 12 | (12 - 4) * 100 / 16 | 50 |
| 20 | (20 - 4) * 100 / 16 | 100 |
Check the result: A 12 mA sample produces 50 °C, with unitDisplay: °C and the corresponding input timestamp.
The two-stage End-to-End Scenario uses this same scale in a JavaScript Analyzer. It writes to temperature_a, a separate destination from temperature_tf, so the standalone and chained examples do not compete for the same output.
Check the Result and Troubleshoot
- Read the saved Analyzer with Get Analyzer. Check
type, the stream IDs andconfig.expression. - Follow Enable and Check the Result, then wait for a new current sample.
- Query
temperature_tfwith Get Latest Value. ComparedataObject.valueanddataObject.timestampwith the corresponding input.
Check the result: The value follows the calibration formula and belongs to the sample you are verifying. On a changing source, two latest-value requests can observe different samples, so compare timestamps as well as values.
| Observation | What to check |
|---|---|
| 400 Bad Request while saving | Supply one input and one output, reference the declared variable, and check the expression and output paths. |
| 404 Not Found | Confirm the Org, SubNode device, Analyzer and stream IDs. |
| 409 Conflict while creating or updating | The destination may already have a source, or the Analyzer being updated is still enabled. Read its configuration before retrying. |
| Latest query returns 204 No Content | Check the enabled state, new input and output ID. Non-numeric input produces no result for that evaluation. |
| Temperature is implausible | Confirm the input is mA and check the sensor's actual range and calibration. A unit-label change only relabels the number. |
| Result differs from your calculation | Check variable bindings and parentheses, then compare matching timestamps. |
Creating or enabling an Analyzer does not replace checking its output. The next guide explains the JavaScript return and mapping rules used by the complete scenario.