From ca8ec2c102bb2adcd1a2677b8d1c2421c861eb2c Mon Sep 17 00:00:00 2001 From: Andry925 Date: Mon, 29 Dec 2025 19:07:57 +0200 Subject: [PATCH 1/2] add documentation section for ftp custom converter functionality --- docs/iot-gateway/config/ftp.md | 78 ++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/docs/iot-gateway/config/ftp.md b/docs/iot-gateway/config/ftp.md index a2d472fb1b..2480911ee9 100644 --- a/docs/iot-gateway/config/ftp.md +++ b/docs/iot-gateway/config/ftp.md @@ -312,6 +312,84 @@ Let's look at how we can configure this section for different file extensions: ] ``` +#### Subsection "converter" + +This configuration section is **optional** and is used only when you want to process incoming data with a custom FTP converter instead of the built-in **FTPUplinkConverter**. + +Typical use cases: + +- Files with **extensions not supported** by default (.txt, .csv, .json), or Supported extensions, but with a different data structure, for example: + - CSV files without a header line + - CSV lines where fields are located at fixed column positions + +In this example, we show a configuration for a **CSV file without headers**, where device name, attributes and telemetry values are taken by column index. + +| **Parameter** | **Example value** | **Description** | +|----------------------------|-------------------------------|---------------------------------------------------------------------------------------------------------| +| converter.type | **custom** | Tells the FTP connector to use a custom converter instead of the default one. | +| converter.extension | **CustomFTPtUplinkConverter** | Name of the Python class that implements the custom converter. | +| converter.extension-config | **object** | Arbitrary configuration for the custom converter. This object is passed as-is to the converter on init. | + +**extension-config** fields used in this example + +| **Parameter** | **Example value** | **Description** | +|--------------------|-------------------| ------------------------------------------------------------------------------------------------------ | +| devicePatternName | **0** | Column index used to resolve the device name (here: value from column `0`). | +| devicePatternType | **1** | Column index or literal used to resolve the device type (here: value from column `1`). | +| attributes | **array** | List of attribute mappings. Each item describes how to read an attribute value from a specific column. | +| timeseries | **array** | List of timeseries mappings. Each item describes how to read a telemetry value from a specific column. | + +Each item in attributes / timeseries has the following fields: + +| **Field** | **Example value** | **Description** | +|-----------|-------------------------------------| --------------------------------------------------------------------------- | +| key | **meterAddress** | Attribute / telemetry key that will appear in ThingsBoard. | +| column | **0** | Zero-based column index in the CSV line from which the value will be taken. | +| type | **string** / **int** / **double** | Value type. The custom converter will cast the raw string to this type. | + + +{% capture difference %} +The exact behavior will depend on your own `CustomFTPtUplinkConverter` implementation, but this configuration shows a working example for headerless CSV files. +You will most likely change the mapping values (devicePatternName, devicePatternType, attributes, timeseries) to match your file format, but the parameter names and structure must remain the same. +{% endcapture %} +{% include templates/info-banner.md content=difference %} + +Mapping subsection in the configuration looks like: + +```json +{ + "converter": { + "type": "custom", + "extension": "CustomFTPtUplinkConverter", + "extension-config": { + "devicePatternName": 0, + "devicePatternType": 1, + "attributes": [ + { + "key": "meterAddress", + "column": 0, + "type": "string" + } + ], + "timeseries": [ + { + "key": "meterReading", + "column": 2, + "type": "double" + }, + { + "key": "batteryAlert", + "column": 3, + "type": "int" + } + ] + } + } +} +``` +{:.copy-code} + + ### Section "attributeUpdates" From a0d126255451b46701e768c1d72cd07a66fda332 Mon Sep 17 00:00:00 2001 From: Andry925 Date: Mon, 5 Jan 2026 16:48:40 +0200 Subject: [PATCH 2/2] remove tables from fpt parameters description --- docs/iot-gateway/config/ftp.md | 82 ++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/docs/iot-gateway/config/ftp.md b/docs/iot-gateway/config/ftp.md index 2480911ee9..288a09af22 100644 --- a/docs/iot-gateway/config/ftp.md +++ b/docs/iot-gateway/config/ftp.md @@ -193,7 +193,7 @@ Let's look at how we can configure this section for different file extensions: } ] ``` - + That means that FTP converter will look for the following file structure: ```txt temp,hum @@ -314,45 +314,15 @@ Let's look at how we can configure this section for different file extensions: #### Subsection "converter" -This configuration section is **optional** and is used only when you want to process incoming data with a custom FTP converter instead of the built-in **FTPUplinkConverter**. +This configuration section is **optional** and is used only when you want to process incoming data with a custom FTP converter. Typical use cases: -- Files with **extensions not supported** by default (.txt, .csv, .json), or Supported extensions, but with a different data structure, for example: +- Files with **extensions not supported** by default, or supported extensions, but with a different data structure, for example: - CSV files without a header line - CSV lines where fields are located at fixed column positions - -In this example, we show a configuration for a **CSV file without headers**, where device name, attributes and telemetry values are taken by column index. - -| **Parameter** | **Example value** | **Description** | -|----------------------------|-------------------------------|---------------------------------------------------------------------------------------------------------| -| converter.type | **custom** | Tells the FTP connector to use a custom converter instead of the default one. | -| converter.extension | **CustomFTPtUplinkConverter** | Name of the Python class that implements the custom converter. | -| converter.extension-config | **object** | Arbitrary configuration for the custom converter. This object is passed as-is to the converter on init. | - -**extension-config** fields used in this example - -| **Parameter** | **Example value** | **Description** | -|--------------------|-------------------| ------------------------------------------------------------------------------------------------------ | -| devicePatternName | **0** | Column index used to resolve the device name (here: value from column `0`). | -| devicePatternType | **1** | Column index or literal used to resolve the device type (here: value from column `1`). | -| attributes | **array** | List of attribute mappings. Each item describes how to read an attribute value from a specific column. | -| timeseries | **array** | List of timeseries mappings. Each item describes how to read a telemetry value from a specific column. | -Each item in attributes / timeseries has the following fields: - -| **Field** | **Example value** | **Description** | -|-----------|-------------------------------------| --------------------------------------------------------------------------- | -| key | **meterAddress** | Attribute / telemetry key that will appear in ThingsBoard. | -| column | **0** | Zero-based column index in the CSV line from which the value will be taken. | -| type | **string** / **int** / **double** | Value type. The custom converter will cast the raw string to this type. | - - -{% capture difference %} -The exact behavior will depend on your own `CustomFTPtUplinkConverter` implementation, but this configuration shows a working example for headerless CSV files. -You will most likely change the mapping values (devicePatternName, devicePatternType, attributes, timeseries) to match your file format, but the parameter names and structure must remain the same. -{% endcapture %} -{% include templates/info-banner.md content=difference %} +In this example, we show a configuration for a **CSV file without headers**, where device name, attributes and telemetry values are taken by column index. Mapping subsection in the configuration looks like: @@ -389,6 +359,50 @@ Mapping subsection in the configuration looks like: ``` {:.copy-code} +Below are description of each parameter used in this configuration for the custom converter. + +Top-level converter parameters: + +1. **converter.type** + Must be set to **custom**. This tells the FTP connector to use a custom converter instead of the built-in ones. + +2. **converter.extension** + Name of the Python class that implements the custom converter, for example **CustomFTPtUplinkConverter**. + + +Extension-config fields: + +1. **devicePatternName** + Column index used to resolve the device name. In the example, **0** means that the device name is taken from column 0. + +2. **devicePatternType** + Column index or literal used to resolve the device type. In the example, **1** means that the device type is taken from column 1. + +3. **attributes** + An array of attribute mappings. Each item describes how to read a single device attribute from a specific CSV column. + +4. **timeseries** + An array of telemetry mappings. Each item describes how to read a single telemetry value from a specific CSV column. + + +Attributes and timeseries items: +Each element of attributes and timeseries has the same structure: + +1. **key** + Attribute or telemetry key that will appear on the created device in the ThingsBoard Platform (for example, **meterAddress**, **meterReading**). + +2. **column** + Zero-based column index in the CSV line from which the value is taken. + +3. **type** + Target value type. The custom converter will cast the raw string to this type (for example, **string**, **int**, **double**). + +{% capture difference %} +The exact behavior will depend on your own `CustomFTPtUplinkConverter` implementation, but this configuration shows a working example for headerless CSV files. +You will most likely change the mapping values (devicePatternName, devicePatternType, attributes, timeseries) to match your file format, but the parameter names and structure must remain the same. +{% endcapture %} +{% include templates/info-banner.md content=difference %} + ### Section "attributeUpdates"