MeasurementContainer.isUnitCompatible now short-circuits to accept any unit when the measurement type is not in the built-in measureMap. Known types (pressure, flow, power, temperature, volume, length, mass, energy) still validate strictly. This unblocks user-defined types in the measurement node's new digital/MQTT mode — e.g. 'humidity' with unit '%', 'co2' with 'ppm' — without forcing those units into the convert-module unit system. measurement.json schema: add 'mode.current' (analog | digital) and 'channels' (array) so the validator stops stripping them from the runtime config. Ignored in analog mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
478 lines
17 KiB
JSON
478 lines
17 KiB
JSON
{
|
|
"general": {
|
|
"name": {
|
|
"default": "Sensor",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "A human-readable name or label for this measurement configuration."
|
|
}
|
|
},
|
|
"id": {
|
|
"default": null,
|
|
"rules": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "A unique identifier for this configuration. If not provided, defaults to null."
|
|
}
|
|
},
|
|
"unit": {
|
|
"default": "unitless",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "The unit of measurement for this configuration (e.g., 'meters', 'seconds', 'unitless')."
|
|
}
|
|
},
|
|
"logging": {
|
|
"logLevel": {
|
|
"default": "info",
|
|
"rules": {
|
|
"type": "enum",
|
|
"values": [
|
|
{
|
|
"value": "debug",
|
|
"description": "Log messages are printed for debugging purposes."
|
|
},
|
|
{
|
|
"value": "info",
|
|
"description": "Informational messages are printed."
|
|
},
|
|
{
|
|
"value": "warn",
|
|
"description": "Warning messages are printed."
|
|
},
|
|
{
|
|
"value": "error",
|
|
"description": "Error messages are printed."
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"enabled": {
|
|
"default": true,
|
|
"rules": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether logging is active. If true, log messages will be generated."
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"functionality": {
|
|
"softwareType": {
|
|
"default": "measurement",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "Specified software type for this configuration."
|
|
}
|
|
},
|
|
"role": {
|
|
"default": "Sensor",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "Indicates the role this configuration plays (e.g., sensor, controller, etc.)."
|
|
}
|
|
},
|
|
"positionVsParent":{
|
|
"default":"atEquipment",
|
|
"rules": {
|
|
"type": "enum",
|
|
"values": [
|
|
{
|
|
"value": "atEquipment",
|
|
"description": "The measurement is taken at the equipment level, typically representing the overall state or performance of the equipment."
|
|
},
|
|
{
|
|
"value": "upstream",
|
|
"description": "The measurement is taken upstream, meaning it is related to inputs or conditions that affect the equipment's operation, such as supply conditions or environmental factors."
|
|
},
|
|
{
|
|
"value": "downstream",
|
|
"description": "The measurement is taken downstream, indicating it relates to outputs or results of the equipment's operation, such as product quality or performance metrics."
|
|
}
|
|
],
|
|
"description": "Defines the position of the measurement relative to its parent equipment or system."
|
|
}
|
|
},
|
|
"distance":{
|
|
"default": null,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "Defines the position of the measurement relative to its parent equipment or system."
|
|
}
|
|
}
|
|
},
|
|
"asset": {
|
|
"uuid": {
|
|
"default": null,
|
|
"rules": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Asset tag number which is a universally unique identifier for this asset. May be null if not assigned."
|
|
}
|
|
},
|
|
"tagCode":{
|
|
"default": null,
|
|
"rules": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Asset tag code which is a unique identifier for this asset. May be null if not assigned."
|
|
}
|
|
},
|
|
"tagNumber": {
|
|
"default": null,
|
|
"rules": {
|
|
"type": "string",
|
|
"nullable": true,
|
|
"description": "Asset tag number assigned by the asset registry. May be null if not assigned."
|
|
}
|
|
},
|
|
"geoLocation": {
|
|
"default": {
|
|
"x": 0,
|
|
"y": 0,
|
|
"z": 0
|
|
},
|
|
"rules": {
|
|
"type": "object",
|
|
"description": "An object representing the asset's physical coordinates or location.",
|
|
"schema": {
|
|
"x": {
|
|
"default": 0,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "X coordinate of the asset's location."
|
|
}
|
|
},
|
|
"y": {
|
|
"default": 0,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "Y coordinate of the asset's location."
|
|
}
|
|
},
|
|
"z": {
|
|
"default": 0,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "Z coordinate of the asset's location."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"supplier": {
|
|
"default": "Unknown",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "The supplier or manufacturer of the asset."
|
|
}
|
|
},
|
|
"category": {
|
|
"default": "sensor",
|
|
"rules": {
|
|
"type": "enum",
|
|
"values": [
|
|
{
|
|
"value": "sensor",
|
|
"description": "A device that detects or measures a physical property and responds to it (e.g. temperature sensor)."
|
|
},
|
|
{
|
|
"value": "measurement",
|
|
"description": "Measurement software category used by the asset menu for this node."
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"type": {
|
|
"default": "pressure",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "A more specific classification within 'type'. For example, 'pressure' for a pressure sensor."
|
|
}
|
|
},
|
|
"model": {
|
|
"default": "Unknown",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "A user-defined or manufacturer-defined model identifier for the asset."
|
|
}
|
|
},
|
|
"unit": {
|
|
"default": "unitless",
|
|
"rules": {
|
|
"type": "string",
|
|
"description": "The unit of measurement for this asset (e.g., 'meters', 'seconds', 'unitless')."
|
|
}
|
|
},
|
|
"accuracy": {
|
|
"default": null,
|
|
"rules": {
|
|
"type": "number",
|
|
"nullable": true,
|
|
"description": "The accuracy of the sensor, typically represented as a percentage or absolute value."
|
|
}
|
|
},
|
|
"repeatability": {
|
|
"default": null,
|
|
"rules": {
|
|
"type": "number",
|
|
"nullable": true,
|
|
"description": "The repeatability of the sensor, typically represented as a percentage or absolute value."
|
|
}
|
|
}
|
|
},
|
|
"assetRegistration": {
|
|
"default": {
|
|
"profileId": 1,
|
|
"locationId": 1,
|
|
"processId": 1,
|
|
"status": "actief",
|
|
"childAssets": []
|
|
},
|
|
"rules": {
|
|
"type": "object",
|
|
"schema": {
|
|
"profileId": {
|
|
"default": 1,
|
|
"rules": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
"locationId": {
|
|
"default": 1,
|
|
"rules": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
"processId": {
|
|
"default": 1,
|
|
"rules": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
"status": {
|
|
"default": "actief",
|
|
"rules": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"childAssets": {
|
|
"default": [],
|
|
"rules": {
|
|
"type": "array",
|
|
"itemType": "string",
|
|
"minLength": 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"scaling": {
|
|
"enabled": {
|
|
"default": false,
|
|
"rules": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether input scaling is active. If true, input values will be scaled according to the parameters below."
|
|
}
|
|
},
|
|
"inputMin": {
|
|
"default": 0,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "The minimum expected input value before scaling."
|
|
}
|
|
},
|
|
"inputMax": {
|
|
"default": 1,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "The maximum expected input value before scaling."
|
|
}
|
|
},
|
|
"absMin": {
|
|
"default": 50,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "The absolute minimum value that can be read or displayed after scaling."
|
|
}
|
|
},
|
|
"absMax": {
|
|
"default": 100,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "The absolute maximum value that can be read or displayed after scaling."
|
|
}
|
|
},
|
|
"offset": {
|
|
"default": 0,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "A constant offset to apply to the scaled output (e.g., to calibrate zero-points)."
|
|
}
|
|
}
|
|
},
|
|
"smoothing": {
|
|
"smoothWindow": {
|
|
"default": 10,
|
|
"rules": {
|
|
"type": "number",
|
|
"min": 1,
|
|
"description": "Determines the size of the data window (number of samples) used for smoothing operations."
|
|
}
|
|
},
|
|
"smoothMethod": {
|
|
"default": "mean",
|
|
"rules": {
|
|
"type": "enum",
|
|
"values": [
|
|
{
|
|
"value": "none",
|
|
"description": "No smoothing is applied; raw data is passed through."
|
|
},
|
|
{
|
|
"value": "mean",
|
|
"description": "Calculates the simple arithmetic mean (average) of the data points in a window."
|
|
},
|
|
{
|
|
"value": "min",
|
|
"description": "Selects the smallest (minimum) value among the data points in a window."
|
|
},
|
|
{
|
|
"value": "max",
|
|
"description": "Selects the largest (maximum) value among the data points in a window."
|
|
},
|
|
{
|
|
"value": "sd",
|
|
"description": "Computes the standard deviation to measure the variation or spread of the data."
|
|
},
|
|
{
|
|
"value": "lowPass",
|
|
"description": "Filters out high-frequency components, allowing only lower frequencies to pass."
|
|
},
|
|
{
|
|
"value": "highPass",
|
|
"description": "Filters out low-frequency components, allowing only higher frequencies to pass."
|
|
},
|
|
{
|
|
"value": "weightedMovingAverage",
|
|
"description": "Applies varying weights to each data point in a window before averaging."
|
|
},
|
|
{
|
|
"value": "bandPass",
|
|
"description": "Filters the signal to allow only frequencies within a specific range to pass."
|
|
},
|
|
{
|
|
"value": "median",
|
|
"description": "Selects the median (middle) value in a window, minimizing the effect of outliers."
|
|
},
|
|
{
|
|
"value": "kalman",
|
|
"description": "Applies a Kalman filter to combine noisy measurements over time for more accurate estimates."
|
|
},
|
|
{
|
|
"value": "savitzkyGolay",
|
|
"description": "Uses a polynomial smoothing filter on a moving window, which can also provide derivative estimates."
|
|
}
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"simulation": {
|
|
"enabled": {
|
|
"default": false,
|
|
"rules": {
|
|
"type": "boolean",
|
|
"description": "If true, the system operates in simulation mode, generating simulated values instead of using real inputs."
|
|
}
|
|
},
|
|
"safeCalibrationTime": {
|
|
"default": 100,
|
|
"rules": {
|
|
"type": "number",
|
|
"min": 100,
|
|
"description": "Time to wait before finalizing calibration in simulation mode (in milliseconds or appropriate unit)."
|
|
}
|
|
}
|
|
},
|
|
"interpolation": {
|
|
"percentMin": {
|
|
"default": 0,
|
|
"rules": {
|
|
"type": "number",
|
|
"min": 0,
|
|
"description": "Minimum percentage for interpolation or data scaling operations."
|
|
}
|
|
},
|
|
"percentMax": {
|
|
"default": 100,
|
|
"rules": {
|
|
"type": "number",
|
|
"max": 100,
|
|
"description": "Maximum percentage for interpolation or data scaling operations."
|
|
}
|
|
}
|
|
},
|
|
"mode": {
|
|
"current": {
|
|
"default": "analog",
|
|
"rules": {
|
|
"type": "enum",
|
|
"values": [
|
|
{
|
|
"value": "analog",
|
|
"description": "Single-scalar input mode (classic 4-20mA / PLC style). msg.payload is a number; the node runs one offset/scaling/smoothing/outlier pipeline and emits one MeasurementContainer slot."
|
|
},
|
|
{
|
|
"value": "digital",
|
|
"description": "Multi-channel input mode (MQTT / IoT JSON style). msg.payload is an object keyed by channel names declared under config.channels; the node routes each key through its own pipeline and emits N slots from one input message."
|
|
}
|
|
],
|
|
"description": "Selects how incoming msg.payload is interpreted."
|
|
}
|
|
}
|
|
},
|
|
"channels": {
|
|
"default": [],
|
|
"rules": {
|
|
"type": "array",
|
|
"itemType": "object",
|
|
"minLength": 0,
|
|
"description": "Channel map used in digital mode. Each entry is a self-contained pipeline definition: {key, type, position, unit, scaling?, smoothing?, outlierDetection?, distance?}. Ignored in analog mode."
|
|
}
|
|
},
|
|
"outlierDetection": {
|
|
"enabled": {
|
|
"default": false,
|
|
"rules": {
|
|
"type": "boolean",
|
|
"description": "Indicates whether outlier detection is enabled. If true, outliers will be identified and handled according to the method specified."
|
|
}
|
|
},
|
|
"method": {
|
|
"default": "zScore",
|
|
"rules": {
|
|
"type": "enum",
|
|
"values": [
|
|
{
|
|
"value": "zScore",
|
|
"description": "Uses the Z-score method to identify outliers based on standard deviations from the mean."
|
|
},
|
|
{
|
|
"value": "iqr",
|
|
"description": "Uses the Interquartile Range (IQR) method to identify outliers based on the spread of the middle 50% of the data."
|
|
},
|
|
{
|
|
"value": "modifiedZScore",
|
|
"description": "Uses a modified Z-score method that is more robust to small sample sizes."
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"threshold": {
|
|
"default": 3,
|
|
"rules": {
|
|
"type": "number",
|
|
"description": "The threshold value used by the selected outlier detection method. For example, a Z-score threshold of 3.0."
|
|
}
|
|
}
|
|
}
|
|
} |