diff --git a/_includes/head-header.html b/_includes/head-header.html
index c715785766..c42d9060c3 100644
--- a/_includes/head-header.html
+++ b/_includes/head-header.html
@@ -614,6 +614,54 @@
}
}
+
+
diff --git a/_includes/releases-table.sass b/_includes/releases-table.sass
new file mode 100644
index 0000000000..a77643a673
--- /dev/null
+++ b/_includes/releases-table.sass
@@ -0,0 +1,233 @@
+.releases-table
+ max-width: 2000px
+ border-radius: 8px
+ border: 12px solid rgba(42,125,236,0.001)
+ background: rgba(42, 125, 236, 0.08)
+ overflow-x: auto
+ .releases-table-content
+ min-width: 1300px
+ width: 100%
+ .releases-table-header-item.cur-patch
+ @media (max-width: 1280px)
+ display: none
+ .releases-table-header-item, .releases-table-content-item
+ &:nth-child(1)
+ min-width: 80px
+ &:nth-child(2)
+ min-width: 135px
+ &:nth-child(3)
+ min-width: 175px
+ &:nth-child(4)
+ min-width: 135px
+ &:nth-child(5)
+ min-width: 180px
+ &:nth-child(6)
+ min-width: 400px
+ &:nth-child(7)
+ text-align: center
+ min-width: 130px
+ .releases-table-header
+ padding: 12px 24px
+ background: #FFF
+ border-radius: 4px
+ display: flex
+ justify-content: space-between
+ margin-bottom: 4px
+ .releases-table-header-item
+ font-size: 16px
+ font-weight: 500
+ line-height: 32px
+ color: rgba(0, 0, 0, 0.87)
+ .releases-table-row
+ padding: 0 4px
+ border-radius: 4px
+ background: #FFF
+ .releases-table-content-wrapper
+ display: block
+ padding: 4px 0 3px
+ border-bottom: 1px solid rgba(0, 0, 0, 0.12)
+ &:last-child
+ border-bottom: none
+ .releases-table-content
+ border-left: 3px solid transparent
+ background: transparent
+ transition: ease-in-out 0.25s
+ padding: 12px 20px
+ display: flex
+ justify-content: space-between
+ align-items: center
+ max-height: 48px
+ &:hover
+ border-left: 3px solid #2A7DEC
+ background: linear-gradient(0deg, rgba(109, 109, 109, 0.04) 0%, rgba(109, 109, 109, 0.04) 100%), #FFF
+ .releases-table-content-item:not(.upgrade-link, .upgrade-instructions)
+ scale: 1.1
+ .releases-table-content-item.cur-patch
+ @media (max-width: 1280px)
+ display: none
+ .releases-table-content-item
+ text-decoration-color: #000
+ transition: ease-in-out 0.25s
+ font-size: 15px
+ line-height: 24px
+ scale: 1
+ &.old-date
+ color: rgba(0, 0, 0, 0.38)
+ &.version-link
+ display: flex
+ align-items: center
+ gap: 6px
+ span
+ font-weight: 400
+ color: rgba(0, 0, 0, 0.87)
+ &.version-link.version-link-lts
+ &:hover
+ text-decoration-color: #2A7DEC
+ &.upgrade-link
+ display: flex
+ justify-content: center
+ a
+ display: block
+ padding: 4px 14px
+ font-size: 16px
+ line-height: 28px
+ color: rgba(0, 0, 0, 0.76)
+ width: fit-content
+ background: transparent
+ font-weight: 500
+ border-radius: 4px
+ border: 1px solid rgba(0, 0, 0, 0.12)
+ &:hover
+ text-decoration: none
+ color: #2A7DEC
+ border: 1px solid #2A7DEC
+ background: rgba(42, 125, 236, 0.08)
+
+.releases-table.pe-table
+ background: rgba(0, 105, 92, 0.06)
+ border: 12px solid rgba(0, 105, 92, 0.001)
+ .releases-table-content-wrapper
+ .releases-table-content
+ &:hover
+ border-left: 3px solid #00695C
+ .releases-table-content-item
+ &.version-link.version-link-lts
+ &:hover
+ text-decoration-color: #00695C
+ &.upgrade-link
+ a
+ &:hover
+ color: #00695C
+ border: 1px solid #00695C
+ background: rgba(0, 105, 92, 0.08)
+
+.releases-table.upgrade-instructions-table
+ margin: 30px 0
+ .releases-table-content
+ min-width: 1100px
+ .releases-table-header-item, .releases-table-content-item
+ min-width: 130px
+ &:nth-child(1)
+ min-width: 80px
+ &:nth-child(2)
+ min-width: 131px
+ &:nth-child(3)
+ min-width: 176px
+ &:nth-child(5)
+ min-width: 141px
+ &:nth-child(6)
+ text-align: center
+ min-width: 240px
+ .releases-table-header
+ .releases-table-header-item
+ a
+ font-weight: 500 !important
+ color: rgba(0, 0, 0, 0.87)
+ text-decoration: underline
+ &:hover
+ text-decoration: none
+ color: #2A7DEC
+ .releases-table-content-wrapper
+ .releases-table-content
+ &:hover
+ .releases-table-content-item.upgrade-instructions
+ a
+ img
+ filter: unset
+ a:not(:hover)
+ img
+ scale: 1
+ .releases-table-content-item
+ &.lts-item
+ span
+ color: rgba(0, 0, 0, 0.54)
+ border-radius: 16px
+ background: rgba(0, 0, 0, 0.06)
+ padding: 4px 10px
+ span.lts-item-true
+ color: #198038
+ background: rgba(25, 128, 56, 0.06)
+
+ &.upgrade-instructions
+ display: flex
+ align-items: center
+ justify-content: center
+ gap: 5px
+
+ a
+ position: relative
+ padding: 10px
+
+ &.right-link
+ &:before
+ left: -100%
+
+ &:before
+ content: attr(data-tooltip)
+ position: absolute
+ bottom: 125%
+ left: 37%
+ transform: translateX(-50%)
+ background-color: rgba(0,0,0,0.7)
+ backdrop-filter: blur(2px)
+ color: #fff
+ font-size: 13px
+ padding: 6px 8px
+ border-radius: 6px
+ white-space: nowrap
+ opacity: 0
+ pointer-events: none
+ transition: opacity 0.2s ease
+
+ &:hover
+ &:before
+ opacity: 1
+ content: attr(data-tooltip)
+ img
+ scale: 1.2
+
+ img
+ scale: 1
+ filter: brightness(0) saturate(100%) invert(57%) sepia(2%) saturate(45%) hue-rotate(44deg) brightness(88%) contrast(90%)
+ transition: ease-in-out 0.3s
+
+.legend
+ li.list-link
+ &::marker, a
+ color: #2A7DEC
+
+.legend.pe
+ li.list-link
+ &::marker, a
+ color: var(--tb-main-color)
+
+.fixed-upgrade-scrollbar
+ position: fixed
+ bottom: 0
+ width: 100%
+ background: #eeeeee
+ overflow-x: auto
+ display: none
+ z-index: 99999999
+ .scrollbar-inner
+ height: 1px
diff --git a/_includes/resources.liquid b/_includes/resources.liquid
new file mode 100644
index 0000000000..083d23d3f1
--- /dev/null
+++ b/_includes/resources.liquid
@@ -0,0 +1,25 @@
+{%- assign pe = include.pe -%}
+{%- assign last = include.last -%}
+
+{%- if pe == "true" -%}
+ {%- assign data = site.data.pe.resources -%}
+{%- else -%}
+ {%- assign data = site.data.resources -%}
+{%- endif -%}
+
+{%- if last == "true" -%}
+ {%- assign pair = data | first -%}
+ {%- assign versionEntry = pair[1] -%}
+{%- else -%}
+ {%- assign version = include.version -%}
+ {%- assign versionEntry = data[version] -%}
+{%- endif -%}
+
+{%- assign kind = include.kind -%}
+
+{%- if versionEntry and versionEntry[kind] -%}
+```bash
+{{ versionEntry[kind] }}
+```
+{: .copy-code}
+{%- endif -%}
\ No newline at end of file
diff --git a/_includes/templates/adding-widget.md b/_includes/templates/adding-widget.md
new file mode 100644
index 0000000000..f6e0c65f72
--- /dev/null
+++ b/_includes/templates/adding-widget.md
@@ -0,0 +1,4 @@
+
+- Open your dashboard and switch to **[Edit mode](/docs/{{docsPrefix}}user-guide/dashboards/#edit-mode){:target="_blank"}**.
+- Click "**[Add widget](/docs/{{docsPrefix}}user-guide/dashboards/#add-new-widget){:target="_blank"}**" at the top of the screen.
+- Choose the **{{widgetName}}** widget from the **{{widgetBundle}}** widget bundle and place it on the dashboard.
\ No newline at end of file
diff --git a/_includes/templates/device-library/single-board-computers/device-imported-dashboard.md b/_includes/templates/device-library/single-board-computers/device-imported-dashboard.md
index 71b29c3ef5..7e3e214908 100644
--- a/_includes/templates/device-library/single-board-computers/device-imported-dashboard.md
+++ b/_includes/templates/device-library/single-board-computers/device-imported-dashboard.md
@@ -1,8 +1,8 @@
### Import dashboard
You are able to import a dashboard in JSON format. To import a dashboard, you should go to the Dashboard group and click
- on the “+” button in the upper right corner of the page and choose “Import dashboard”. The dashboard import window
-should pop up, and you will be prompted to upload the JSON file and click “Import”.
+ the **“+”** button in the upper right corner of the page and choose **“Import dashboard”**. The dashboard import window
+should pop up, and you will be prompted to upload the **JSON** file and click **“Import”**.
{% assign importingDashboardCE = '
===
@@ -24,8 +24,32 @@ should pop up, and you will be prompted to upload the JSON file and click “Imp
'
%}
+{% assign importingDashboardEdgeCE = '
+ ===
+ image: /images/edge/config/general/import-dashboard-1-ce.webp,
+ ===
+ image: /images/edge/config/general/import-dashboard-2-ce.webp,
+ ===
+ image: /images/edge/config/general/import-dashboard-3-ce.webp,
+'
+%}
+
+{% assign importingDashboardEdgePE = '
+ ===
+ image: /images/edge/config/general/import-dashboard-1-pe.webp,
+ ===
+ image: /images/edge/config/general/import-dashboard-2-pe.webp,
+ ===
+ image: /images/edge/config/general/import-dashboard-3-pe.webp,
+'
+%}
+
{% if page.docsPrefix == "pe/" or page.docsPrefix contains "paas/" or docsPrefix == "pe/" or docsPrefix contains "paas/" %}
{% include images-gallery.liquid showListImageTitles="true" imageCollection=importingDashboardPE %}
+{% elsif page.docsPrefix == "pe/edge/" %}
+ {% include images-gallery.liquid showListImageTitles="true" imageCollection=importingDashboardEdgePE %}
+{% elsif page.docsPrefix == "edge/" %}
+ {% include images-gallery.liquid showListImageTitles="true" imageCollection=importingDashboardEdgeCE %}
{% else %}
{% include images-gallery.liquid showListImageTitles="true" imageCollection=importingDashboardCE %}
{% endif %}
@@ -39,4 +63,4 @@ To do this - we need to press the pen icon and select entity aliases, select ali
Then, choose a device with name My device from dropdown list and save entity alias. Now, you should be able to see the data from the device.
If you did everything right, you have to see the following dashboard:
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/_includes/templates/device-library/single-board-computers/device-new-dashboard.md b/_includes/templates/device-library/single-board-computers/device-new-dashboard.md
index 04bbca57b2..d3e084296f 100644
--- a/_includes/templates/device-library/single-board-computers/device-new-dashboard.md
+++ b/_includes/templates/device-library/single-board-computers/device-new-dashboard.md
@@ -1,34 +1,64 @@
-### Create new dashboard
+### Create a New Dashboard
We will create a dashboard and add the most popular widgets. See the instructions below.
{% assign creatingNewDashboardPE = '
===
image: /images/helloworld/getting-started-pe/hello-world-3-1-create-empty-dashboard-1-pe.png,
- title: Open the Dashboards page. Click on the "+" icon in the top right corner. Select "Create new dashboard";
+ title: Open the **Dashboards** page. Click on the **"+"** icon in the top right corner. Select **"Create new dashboard"**;
===
image: /images/helloworld/getting-started-pe/hello-world-3-1-create-empty-dashboard-2-pe.png,
- title: Input dashboard name. For example, "My New Dashboard". Click "Add" to add the dashboard;
+ title: Input dashboard name. For example, "My New Dashboard". Click **"Add"** to add the dashboard;
===
image: /images/helloworld/getting-started-pe/hello-world-3-1-create-empty-dashboard-3-pe.png,
- title: Your dashboard should be listed first since the table sorts dashboards using the time of the creation by default. Click on the "Open dashboard" icon.
+ title: Your dashboard should be listed first since the table sorts dashboards using the time of the creation by default. Click on the **"Open dashboard"** icon.
'
%}
{% assign creatingNewDashboardCE = '
===
image: /images/helloworld/getting-started-ce/hello-world-3-1-create-empty-dashboard-1-ce.png,
- title: Open the Dashboards page. Click on the "+" icon in the top right corner. Select "Create new dashboard";
+ title: Open the Dashboards page. Click on the **"+"** icon in the top right corner. Select **"Create new dashboard"**;
===
image: /images/helloworld/getting-started-ce/hello-world-3-1-create-empty-dashboard-2-ce.png,
- title: Input dashboard name. For example, "My New Dashboard". Click "Add" to add the dashboard;
+ title: Input dashboard name. For example, "My New Dashboard". Click **"Add"** to add the dashboard;
===
image: /images/helloworld/getting-started-ce/hello-world-3-1-create-empty-dashboard-3-ce.png,
- title: Your dashboard should be listed first since the table sorts dashboards using the creation time of the creation by default. Click on the "Open dashboard" icon.
+ title: Your dashboard should be listed first since the table sorts dashboards using the creation time of the creation by default. Click on the **"Open dashboard"** icon.
'
%}
+{% assign creatingNewDashboardEdgePE = '
+ ===
+ image: /images/edge/config/general/create-new-dashboard-pe.webp,
+ title: Open the Dashboards page. Click on the **"+"** icon in the top right corner. Select **"Create new dashboard"**;
+ ===
+ image: /images/edge/config/general/new-dashboard-dialog-pe.webp,
+ title: In the pop-up window, enter a dashboard title. Other fields are optional. Click the **"Add"** button to proceed;
+ ===
+ image: /images/edge/config/general/dashboard-edit-mode-pe.webp,
+ title: After creating the dashboard, you will automatically transition to edit mode.
+'
+%}
+
+{% assign creatingNewDashboardEdgeCE = '
+ ===
+ image: /images/edge/config/general/create-new-dashboard.webp,
+ title: Go to the **Dashboards** section. Click on the **"+"** icon in the top right corner. Select **"Create new dashboard"**;
+ ===
+ image: /images/edge/config/general/new-dashboard-dialog.webp,
+ title: In the pop-up window, enter a dashboard title. Other fields are optional. Click the **"Add"** button to proceed;
+ ===
+ image: /images/edge/config/general/dashboard-edit-mode.webp,
+ title: After creating the dashboard, you will automatically transition to edit mode.
+'
+%}
+
{% if page.docsPrefix == "pe/" or page.docsPrefix contains "paas/" or docsPrefix == "pe/" or docsPrefix contains "paas/" %}
{% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingNewDashboardPE %}
+{% elsif page.docsPrefix == "pe/edge/" %}
+ {% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingNewDashboardEdgePE %}
+{% elsif page.docsPrefix == "edge/" %}
+ {% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingNewDashboardEdgeCE %}
{% else %}
{% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingNewDashboardCE %}
{% endif %}
@@ -83,8 +113,50 @@ type or related to a certain asset. You may learn more about different aliases h
'
%}
+{% assign creatingEntityAliasEdgeCE = '
+ ===
+ image: /images/edge/config/general/create-alias-1-ce.webp,
+ title: In the dashboard edit mode, click the **"Entity aliases"** icon in the top right corner.
+ ===
+ image: /images/edge/config/general/create-alias-2-ce.webp,
+ title: Click **“Add alias”**.
+ ===
+ image: /images/edge/config/general/create-alias-3-ce.webp,
+ title: Enter the alias name (for example, “My Device”). Select **"Single entity"** as the filter type and **"Device"** as the type. Then, select the device from the drop-down menu. Click the **"Add"** button.
+ ===
+ image: /images/edge/config/general/create-alias-4-ce.webp,
+ title: Click **"Save"** to save the entity alias.
+ ===
+ image: /images/edge/config/general/create-alias-5-ce.webp,
+ title: Finally, click **"Save"** on the dashboard editor page to save the changes. Then, re-enter edit mode.
+'
+%}
+
+{% assign creatingEntityAliasEdgePE = '
+ ===
+ image: /images/edge/config/general/create-alias-1-pe.webp,
+ title: In the dashboard edit mode, click the **"Entity aliases"** icon in the top right corner.
+ ===
+ image: /images/edge/config/general/create-alias-2-pe.webp,
+ title: Click **“Add alias”**.
+ ===
+ image: /images/edge/config/general/create-alias-3-pe.webp,
+ title: Enter the alias name (for example, “My Device”). Select **"Single entity"** as the filter type and **"Device"** as the type. Then, select the device from the drop-down menu. Click the **"Add"** button.
+ ===
+ image: /images/edge/config/general/create-alias-4-pe.webp,
+ title: Click **"Save"** to save the entity alias.
+ ===
+ image: /images/edge/config/general/create-alias-5-pe.webp,
+ title: Finally, click **"Save"** on the dashboard editor page to save the changes. Then, re-enter edit mode.
+'
+%}
+
{% if page.docsPrefix == "pe/" or page.docsPrefix contains "paas/" or docsPrefix == "pe/" or docsPrefix contains "paas/" %}
{% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingEntityAliasPE %}
+{% elsif page.docsPrefix == "pe/edge/" %}
+ {% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingEntityAliasEdgePE %}
+{% elsif page.docsPrefix == "edge/" %}
+ {% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingEntityAliasEdgeCE %}
{% else %}
{% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingEntityAliasCE %}
{% endif %}
@@ -93,8 +165,8 @@ To add the new widget, we need to select it from the widget library. The widgets
Each widget has a data source. It is how the widget “knows” what data to display. We should configure the data source
to see the latest value of our “cpu_usage” data that we sent during step 2.
-- Enter edit mode. Click on the "Add new widget" button;
-- Select the "Charts" widget bundle. Click on the header of the Entities widget. The "Add Widget" window will appear;
-- Click "Add" to add the data source. A widget may have multiple data sources, but we will use only one;
-- Select the "{{deviceName}}" entity alias. Then click on the input field on the right. The auto-complete with available data points will appear. Select the "cpu_usage" data point and click "Add";
+- Enter the edit mode. Click the **"Add new widget"** button;
+- Select the **"Charts"** widget bundle. Click on the header of the Entities widget. The **"Add Widget"** window will appear;
+- Click **"Add"** to add the data source. A widget may have multiple data sources, but we will use only one;
+- Select the **"{{deviceName}}"** entity alias. Then click on the input field on the right. The auto-complete with available data points will appear. Select the **"cpu_usage"** data point and click **"Add"**;
- To enlarge the widget by dragging its bottom right corner. Feel free to explore advanced settings for additional widget modifications.
\ No newline at end of file
diff --git a/_includes/templates/edge/devices-library/install-edge-gw.md b/_includes/templates/edge/devices-library/install-edge-gw.md
new file mode 100644
index 0000000000..b6e60f7ed1
--- /dev/null
+++ b/_includes/templates/edge/devices-library/install-edge-gw.md
@@ -0,0 +1,45 @@
+{% include /templates/edge/user-guide/starting-edge-on-device.md %}
+
+To proceed with the **Edge installation** on the **{{deviceName}}**, you need to initiate an **SSH (Secure Shell)** connection.
+
+{% if page.url contains "raspberry-pi" %}
+{% include /templates/edge/devices-library/rpi-enable-ssh.md %}
+{% endif %}
+
+To initiate an **SSH (Secure Shell)** connection to the **{{deviceName}}**, open the Terminal and run the following command:
+
+```bash
+ssh {{userName}}@ip_address #Enter the actual IP address
+```
+{: .copy-code}
+
+**ip_address:** Replace "_ip_address_" with the actual IP address of the **{{deviceName}}**.
+**Password:** The Terminal will request the password. {% if page.url contains "raspberry-pi" %}_The default password is `raspberry`._{% endif %}
+{% if page.url contains "nvidia" %}_The default password is `nvidia`._{% endif %}
+
+Once connected, follow the installation instructions below. Start by creating a new directory:
+
+```bash
+mkdir tb_edge
+```
+{: .copy-code}
+
+Open this directory:
+
+```bash
+cd /home/{{userName}}/tb_edge
+```
+{: .copy-code}
+
+{% include /templates/edge/user-guide/preset-edge-config-for-docker.md %}
+
+To set up a local port forwarding via SSH, open **another terminal tab** and run the following command:
+
+```bash
+ssh -N -L 8080:127.0.0.1:8080 {{userName}}@ip_address #Enter the actual IP address
+```
+{: .copy-code}
+
+Any connection to **localhost:8080** on your local machine will be forwarded to **127.0.0.1:8080** on the **{{deviceName}}**.
+
+The **ThingsBoard Edge** instance is available at [**http://127.0.0.1:8080**](http://127.0.0.1:8080){: target="_blank"}. Use your credentials to log in.
diff --git a/_includes/templates/edge/devices-library/rpi-enable-ssh.md b/_includes/templates/edge/devices-library/rpi-enable-ssh.md
new file mode 100644
index 0000000000..c823571df1
--- /dev/null
+++ b/_includes/templates/edge/devices-library/rpi-enable-ssh.md
@@ -0,0 +1,34 @@
+
+For security reasons, **SSH** is disabled by default on all **Raspberry Pi** devices.
+You need to enable it to continue.
+If you have a monitor and keyboard connected, you can enable **SSH** during storage device setup, via the GUI, or in the Terminal.
+
+To enable **SSH** in the Terminal, run:
+
+```bash
+sudo raspi-config
+```
+{: .copy-code}
+
+On the **Raspberry Pi Software Configuration Tool (raspi-config)** page:
+
+{% assign raspi-config = '
+===
+image: /images/devices-library/edge/paspberry-pi/1-raspi-config-interface-options.webp,
+title: Go to **Interface Options** and press **Enter** to select it.
+===
+image: /images/devices-library/edge/paspberry-pi/2-raspi-config-enable-ssh.webp,
+title: Select the **"Enable/disable remote command line access using SSH"** option and press Enter.
+===
+image: /images/devices-library/edge/paspberry-pi/3-raspi-config-confirm-enable-ssh.webp,
+title: Select **Yes** to confirm that the SSH server is to be enabled
+===
+image: /images/devices-library/edge/paspberry-pi/4-raspi-config-ssh-server-enabled-ok.webp,
+title: A confirmation message should appear indicating that the **SSH server is enabled**.
+===
+image: /images/devices-library/edge/paspberry-pi/5-raspi-config-finish.webp,
+title: Select **Finish** and close the program.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=raspi-config %}
\ No newline at end of file
diff --git a/_includes/templates/edge/install/docker-queue-hybrid.md b/_includes/templates/edge/install/docker-queue-hybrid.md
index 772ab0380e..9202fb85d8 100644
--- a/_includes/templates/edge/install/docker-queue-hybrid.md
+++ b/_includes/templates/edge/install/docker-queue-hybrid.md
@@ -45,7 +45,7 @@ services:
- tb-edge-postgres-data:/var/lib/postgresql/data
kafka:
restart: always
- image: bitnamilegacy/kafka:3.8.1
+ image: bitnamilegacy/kafka:4.0
ports:
- 9092
- 9093 #for Kraft
diff --git a/_includes/templates/edge/install/docker-queue-kafka.md b/_includes/templates/edge/install/docker-queue-kafka.md
index 6827a17e43..5718628144 100644
--- a/_includes/templates/edge/install/docker-queue-kafka.md
+++ b/_includes/templates/edge/install/docker-queue-kafka.md
@@ -42,7 +42,7 @@ services:
- tb-edge-postgres-data:/var/lib/postgresql/data
kafka:
restart: always
- image: bitnamilegacy/kafka:3.8.1
+ image: bitnamilegacy/kafka:4.0
ports:
- 9092
- 9093 #for Kraft
diff --git a/_includes/templates/edge/install/pe-docker-queue-hybrid.md b/_includes/templates/edge/install/pe-docker-queue-hybrid.md
index 439e71b6fe..241caaeb88 100644
--- a/_includes/templates/edge/install/pe-docker-queue-hybrid.md
+++ b/_includes/templates/edge/install/pe-docker-queue-hybrid.md
@@ -48,7 +48,7 @@ services:
- tb-edge-postgres-data:/var/lib/postgresql/data
kafka:
restart: always
- image: bitnamilegacy/kafka:3.8.1
+ image: bitnamilegacy/kafka:4.0
ports:
- 9092
- 9093 #for Kraft
diff --git a/_includes/templates/edge/install/pe-docker-queue-kafka.md b/_includes/templates/edge/install/pe-docker-queue-kafka.md
index 7914da7f8d..7e43022947 100644
--- a/_includes/templates/edge/install/pe-docker-queue-kafka.md
+++ b/_includes/templates/edge/install/pe-docker-queue-kafka.md
@@ -44,7 +44,7 @@ services:
- tb-edge-postgres-data:/var/lib/postgresql/data
kafka:
restart: always
- image: bitnamilegacy/kafka:3.8.1
+ image: bitnamilegacy/kafka:4.0
ports:
- 9092
- 9093 #for Kraft
diff --git a/_includes/templates/edge/install/queue-kafka-in-docker.md b/_includes/templates/edge/install/queue-kafka-in-docker.md
index d2593f3d2f..e320f6f5a0 100644
--- a/_includes/templates/edge/install/queue-kafka-in-docker.md
+++ b/_includes/templates/edge/install/queue-kafka-in-docker.md
@@ -10,7 +10,7 @@ cat > docker-compose-kafka.yml <
+
+ WARNING:
+ It is not allowed to use the Object Types list (except "*") with Object ID range or a list of ranges.
+
+
+{% endcapture %}
+{% include templates/warn-banner.md content=info %}
+
+Example of filtering configuration:
+
+```json
+{
+ "timeseries": [
+ {
+ "key": "${objectName} - ${objectType} | ${units}",
+ "objectType": "analogInput",
+ "objectId": "*",
+ "propertyId": ["presentValue", "statusFlags"]
+ }
+ ]
+}
+```
+
+{% capture difference %}
+More usage examples can be found in the [Example usage](/docs/iot-gateway/config/bacnet/#usage-examples) section.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+#### Report strategy
+
For each time series or attribute, you can enable specific report strategy. This strategy defines how often the
data will be sent to the ThingsBoard server. The following strategies are available:
- **On report period** - sends data to ThingsBoard after the report period;
- **On value change** - sends data to ThingsBoard when the value changes;
-- **On value change and report period** - sends data to ThingsBoard when the value changes or after the report period;
+- **On value change or report period** - sends data to ThingsBoard when the value changes or after the report period;
- **On received** - sends data to ThingsBoard after receiving data from the device (default strategy).

diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/attribute-updates.md b/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/attribute-updates.md
new file mode 100644
index 0000000000..08536e1867
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/attribute-updates.md
@@ -0,0 +1,109 @@
+Attribute updates allow you to update objects values on the BACnet device. You can add new attribute updates in the
+“**Attribute updates**” section of the device configuration page.
+
+As an example, we will use a BACnet controller to which a relay is connected. We also know that the relay has the
+following object ID: `Binary Input:1`. We added this Object ID as a telemetry parameter with the key `relay`. We used
+telemetry so that later it would be convenient for us to see if the value we changed using the attribute update
+has changed. You, also, can add this telemetry datapoint to the device configuration or use the reserved `get` method
+to check the value of the node.
+
+Let’s add an attribute update to our configuration. For this purpose, follow these steps:
+
+{% assign attributeUpdates = '
+ ===
+ image: /images/gateway/bacnet-connector/examples/select-created-gateway.png,
+ title: Go to "**Entities**" → "**Gateways**" in the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/bacnet-connector/examples/select-connector-configuration.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/bacnet-connector/examples/select-device-configuration.png,
+ title: Select the created BACnet connector and click on the "**Devices**" tab. Make sure you have configured and connected device (if you don’t know how to do it, see [Application settings](/docs/iot-gateway/config/bacnet/#application) and [Data mapping](/docs/iot-gateway/config/bacnet/#data-mapping) sections of this guide). Click on the “**Pencil**” icon on a device you want to configure attribute updates for.
+ ===
+ image: /images/gateway/bacnet-connector/examples/connector-configuration-attribute-updates-1.png,
+ title: Scroll down to the “**Attribute updates**” section and click on the “**Pencil**” icon to edit the attribute updates.
+ ===
+ image: /images/gateway/bacnet-connector/examples/connector-configuration-attribute-updates-2.png,
+ title: Click on the “**Add attribute update**” button. In our case, we will add `relay` attribute update, so the “**Key**” field, enter `relay`, select the “**Object ID**” as **Analog Input** and "**1**", "**Property ID**" as "**Present Value**".
+ ===
+ image: /images/gateway/bacnet-connector/examples/connector-configuration-attribute-updates-3.png,
+ title: Remember to save your changes by clicking the “**Apply**” button and click save connector configuration button.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=attributeUpdates %}
+
+Now we can check if the attribute update works. Go to "**Entities**" → "**Devices**" → select a created
+device → "**Attributes**" tab → select "**Shared attributes**" → click on the "**+**" icon and add `relay` attribute
+with type "**Boolean**" set it to "**True**".
+
+{% assign attributeUpdates2 = '
+ ===
+ image: /images/gateway/bacnet-connector/examples/connector-configuration-attribute-updates-4.png,
+ ===
+ image: /images/gateway/bacnet-connector/examples/connector-configuration-attribute-updates-5.png,
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="false" imageCollection=attributeUpdates2 %}
+
+Now, let’s check the value of the relay Object ID. In the selected device, go to the "**Last telemetry**" tab and
+check the value of the `relay` telemetry. It should be `true` since we set the shared attribute to `true`.
+
+
+
+Try to change the value of the `relay` shared attribute to `false`. After a few seconds, you should see that the
+`relay` telemetry value has changed to `false`, which means that the attribute update worked correctly.
+
+Full configuration for BACnet connector for the examples above will look like this
+(**make sure to use the right device host and port**):
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "YOUR_HOST",
+ "port": 47808,
+ "objectIdentifier": 599,
+ "vendorIdentifier": 15,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "networkNumber": 3,
+ "deviceDiscoveryTimeoutInSec": 5
+ },
+ "devices": [
+ {
+ "altResponsesAddresses": [],
+ "host": "YOUR_DEVICE_HOST",
+ "port": 47808,
+ "networkMask": "",
+ "deviceInfo": {
+ "deviceNameExpression": "${objectName}",
+ "deviceProfileExpression": "default",
+ "deviceNameExpressionSource": "expression",
+ "deviceProfileExpressionSource": "constant"
+ },
+ "pollPeriod": 10000,
+ "timeseries": [
+ {
+ "key": "relay",
+ "objectType": "binaryInput",
+ "objectId": 1,
+ "propertyId": "presentValue"
+ }
+ ],
+ "attributes": [],
+ "attributeUpdates": [
+ {
+ "key": "relay",
+ "objectType": "binaryInput",
+ "objectId": 1,
+ "propertyId": "presentValue"
+ }
+ ],
+ "serverSideRpc": []
+ }
+ ]
+}
+```
+{:.copy-code}
diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/reserved-rpc.md b/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/reserved-rpc.md
new file mode 100644
index 0000000000..51b325570f
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/reserved-rpc.md
@@ -0,0 +1,113 @@
+Every telemetry and attribute parameter has `GET` and `SET` RPC methods out of the box, so you don’t need to configure
+them manually.
+
+As an example, we will use a BACnet controller to which a relay is connected. We also know that the relay has the
+following object ID: `Binary Input:1`.
+
+We will use this object ID to read the value of the relay using the `GET` RPC method and to set the value of the relay
+using the `SET` RPC method. The configuration for this telemetry will look like this:
+
+```json
+{
+ "key": "relay",
+ "objectType": "binaryInput",
+ "objectId": 1,
+ "propertyId": "presentValue"
+}
+```
+
+Let’s check the value of the relay using the reserved `GET` method. To get the current value of the relay, run the query
+in the RPC debug terminal:
+
+```bash
+get objectType=binaryInput;objectId=1;propertyId=presentValue;
+```
+
+Response:
+
+```json
+{"result": {"value": "inactive"}}
+```
+
+
+
+So, the `GET` method returns the current value of the relay, and we can see that the relay is off.
+
+{% capture difference %}
+The RPC Debug Terminal is used only for example purpose, so you can use any other widget that supports RPC calls.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+To set the value of the relay and turn it on, run the query:
+
+```bash
+set objectType=binaryInput;objectId=1;propertyId=presentValue;value=1;
+```
+
+Response:
+
+```json
+{"result": {"value": 1}}
+```
+
+And as you can see, from the screenshot below, the relay telemetry value has changed to `1`:
+
+
+
+Also, let’s check the value of the relay telemetry again:
+
+```bash
+get objectType=binaryInput;objectId=1;propertyId=presentValue;
+```
+
+Response:
+
+```json
+{"result": {"value": "active"}}
+```
+
+
+
+Full configuration for BACnet connector for the examples above will look like this
+(**make sure to use the right device host and port**):
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "YOUR_HOST",
+ "port": 47808,
+ "objectIdentifier": 599,
+ "vendorIdentifier": 15,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "deviceDiscoveryTimeoutInSec": 5
+ },
+ "devices": [
+ {
+ "altResponsesAddresses": [],
+ "host": "YOUR_DEVICE_HOST",
+ "port": 47808,
+ "deviceInfo": {
+ "deviceNameExpression": "${objectName}",
+ "deviceProfileExpression": "default",
+ "deviceNameExpressionSource": "expression",
+ "deviceProfileExpressionSource": "constant"
+ },
+ "pollPeriod": 10000,
+ "timeseries": [
+ {
+ "key": "relay",
+ "objectType": "binaryInput",
+ "objectId": 1,
+ "propertyId": "presentValue"
+ }
+ ],
+ "attributes": [],
+ "attributeUpdates": [],
+ "serverSideRpc": []
+ }
+ ]
+}
+```
+{:.copy-code}
diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/rpc-to-device.md b/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/rpc-to-device.md
new file mode 100644
index 0000000000..ee3a05e137
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/shared-attributes-and-rpc/rpc-to-device.md
@@ -0,0 +1,99 @@
+RPC to Device allows sending RPC commands to the device that is connected to ThingsBoard directly
+or via Gateway.
+
+As an example, we will use a BACnet controller with temperature sensor. We also know that the temperature sensor has the
+following object ID: `Analog Value:1`, so we will read this value using RPC to Device. To call this method, first,
+we need to configure the BACnet connector to support RPC calls. For this purpose, follow these steps:
+
+{% assign rpcToDevice = '
+ ===
+ image: /images/gateway/bacnet-connector/examples/select-created-gateway.png,
+ title: Go to "**Entities**" → "**Gateways**" in the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/bacnet-connector/examples/select-connector-configuration.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/bacnet-connector/examples/select-device-configuration.png,
+ title: Select the created BACnet connector and click on the "**Devices**" tab. Make sure you have configured and connected device (if you don’t know how to do it, see [Application settings](/docs/iot-gateway/config/bacnet/#application) and [Data mapping](/docs/iot-gateway/config/bacnet/#data-mapping) sections of this guide). Click on the “**Pencil**” icon on a device you want to configure attribute updates for.
+ ===
+ image: /images/gateway/bacnet-connector/examples/rpc-to-device-1.png,
+ title: Scroll down to the "**RPC methods**" section and click on the "**Pencil**" icon to edit the RPC methods.
+ ===
+ image: /images/gateway/bacnet-connector/examples/rpc-to-device-2.png,
+ title: Click on the "**Add method**" button. Fill in the "**Method**" field with `getTemperature`, select the "**Request Type**" as "**Read Property**", "**Object ID**" as "**Analog Value**" and "**1**", and "**Property ID**" as "**Present Value**".
+ ===
+ image: /images/gateway/bacnet-connector/examples/rpc-to-device-3.png,
+ title: Remember to save your changes by clicking the "**Apply**" button and click save connector configuration button.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=rpcToDevice %}
+
+We are done with configuration, so let's check how to call the method. In the RPC Debug Terminal widget, run the
+following command:
+
+```bash
+getTemperature
+```
+
+Response:
+
+
+
+{% capture difference %}
+The RPC Debug Terminal is used only for example purpose, so you can use any other widget that supports RPC calls.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+Full configuration for BACnet connector for the example above will look like
+this (**make sure to use the right device host and port**):
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "YOUR_HOST",
+ "port": 47808,
+ "objectIdentifier": 599,
+ "vendorIdentifier": 15,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "deviceDiscoveryTimeoutInSec": 5
+ },
+ "devices": [
+ {
+ "altResponsesAddresses": [],
+ "host": "YOUR_DEVICE_HOST",
+ "port": 47808,
+ "deviceInfo": {
+ "deviceNameExpression": "${objectName}",
+ "deviceProfileExpression": "default",
+ "deviceNameExpressionSource": "expression",
+ "deviceProfileExpressionSource": "constant"
+ },
+ "pollPeriod": 10000,
+ "timeseries": [
+ {
+ "key": "some-key",
+ "objectType": "binaryInput",
+ "objectId": 1,
+ "propertyId": "presentValue"
+ }
+ ],
+ "attributes": [],
+ "attributeUpdates": [],
+ "serverSideRpc": [
+ {
+ "method": "getTemperature",
+ "objectType": "analogValue",
+ "objectId": 1,
+ "propertyId": "presentValue",
+ "timeout": 5000,
+ "requestType": "readProperty"
+ }
+ ]
+ }
+ ]
+}
+```
+{:.copy-code}
diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/alternative-responses-addresses.md b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/alternative-responses-addresses.md
new file mode 100644
index 0000000000..8ca4fe886f
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/alternative-responses-addresses.md
@@ -0,0 +1,58 @@
+Alternative response addresses field allows you to specify an alternative IP address for device responses.
+It is especially useful when the gateway and the BACnet device are located in different networks.
+
+For example, consider the following network setup:
+
+
+
+In this setup, the gateway runs inside a Docker container and the BACnet device is located on a local network with IP
+address `192.168.1.200:45606` and is not directly accessible from the Docker container. BACPypes sends APDUs to the
+gateway without including the port number, making it impossible for the connector to determine whether a response came
+from an allowed device. When you configure an alternative response address, the connector uses this IP to correctly
+recognize and validate the device.
+
+To configure the alternative response address, you need to add the `altResponsesAddresses` field to the device
+configuration. Here is an example configuration snippet:
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "0.0.0.0",
+ "port": 47808,
+ "mask": 24,
+ "objectIdentifier": 599,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "vendorIdentifier": 15,
+ "deviceDiscoveryTimeoutInSec": 5,
+ "devicesDiscoverPeriodSeconds": 30
+ },
+ "devices": [
+ {
+ "deviceInfo": {
+ "deviceNameExpressionSource": "expression",
+ "deviceNameExpression": "BACnet Device ${objectName}",
+ "deviceProfileExpressionSource": "constant",
+ "deviceProfileExpression": "default"
+ },
+ "host": "192.168.1.200",
+ "port": 45606,
+ "altResponsesAddresses": ["192.168.1.200"],
+ "pollPeriod": 10000,
+ "attributes": [],
+ "timeseries": "*",
+ "attributeUpdates": [],
+ "serverSideRpc": []
+ }
+ ]
+}
+```
+{:.copy-code}
+
+After applying this configuration, the connector will use the specified alternative response address
+`192.168.1.200:45606` to recognize and validate responses from the BACnet device. This ensures that the connector can
+communicate effectively with the device even when they are located in different networks. As a result, you should see
+created device in ThingsBoard:
+
+
diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/discovering-all-device.md b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/discovering-all-device.md
new file mode 100644
index 0000000000..0a1e6c3fb0
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/discovering-all-device.md
@@ -0,0 +1,96 @@
+There are situations when there are many devices with the same list of objects, the values of which need to be read.
+Copying the configuration for each device is not very convenient, so the BACnet connector allows you to automatically
+find all devices on the network and connect them with the same configuration. To do this, you need to specify the host
+and port of the device, as well as set templates for the device name and device profile.
+
+Let's look at an example of how to properly configure automatic device discovery.
+
+Suppose we have two devices with the same list of objects:
+
+| Object Type | Object ID | Property ID | Key |
+|--------------|-----------|---------------|-------------|
+| Analog Input | 1 | Present Value | temperature |
+| Binary Input | 1 | Present Value | relay |
+| Analog Input | 2 | Present Value | humidity |
+| Analog Input | 3 | Present Value | pressure |
+| --- | | | |
+
+To configure automatic device discovery, use the following BACnet connector configuration:
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "YOUR_HOST",
+ "port": 47808,
+ "objectIdentifier": 599,
+ "vendorIdentifier": 15,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "deviceDiscoveryTimeoutInSec": 5
+ },
+ "devices": [
+ {
+ "altResponsesAddresses": [],
+ "host": "*",
+ "port": "*",
+ "deviceInfo": {
+ "deviceNameExpression": "${objectName}",
+ "deviceProfileExpression": "default",
+ "deviceNameExpressionSource": "expression",
+ "deviceProfileExpressionSource": "constant"
+ },
+ "pollPeriod": 10000,
+ "timeseries": [
+ {
+ "key": "temperature",
+ "objectType": "analogInput",
+ "objectId": 1,
+ "propertyId": "presentValue"
+ },
+ {
+ "key": "relay",
+ "objectType": "binaryInput",
+ "objectId": 1,
+ "propertyId": "presentValue"
+ },
+ {
+ "key": "humidity",
+ "objectType": "analogInput",
+ "objectId": 2,
+ "propertyId": "presentValue"
+ },
+ {
+ "key": "pressure",
+ "objectType": "analogInput",
+ "objectId": 3,
+ "propertyId": "presentValue"
+ }
+ ],
+ "attributes": [],
+ "attributeUpdates": [],
+ "serverSideRpc": []
+ }
+ ]
+}
+```
+{:.copy-code}
+
+Below are the main parameters that you can use to properly configure automatic device detection. Let's take a closer
+look at them:
+
+- `host` - you need to specify `*`, this is done so that the connector accepts all IAm messages from all devices on the
+ network.
+- `port` - you need to specify `*`, this is done so that the connector accepts all IAm messages from all devices on the
+ network.
+- `deviceNameExpression` - This is a template for the device name. `${objectName}` is used to match the device name to
+ the object name in the BACnet network.
+- `deviceProfileExpression` - This is a template for a device profile. In our case, we use `default` because all devices
+ have the same type.
+
+After saving the changes and starting the connector, it will send a WhoIs query to the network and start receiving IAm
+messages from all devices. After receiving the IAm message, the connector will automatically create a device for each
+device found with the specified templates and start reading data from the objects. The screenshot below shows what the
+device list looks like after automatic discovery:
+
+
diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/dynamic-device-name-and-profile.md b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/dynamic-device-name-and-profile.md
new file mode 100644
index 0000000000..eea4b46327
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/dynamic-device-name-and-profile.md
@@ -0,0 +1,63 @@
+BACnet connector allows you to set dynamic device names and profiles using expressions. This is especially useful when
+you have multiple devices with similar configurations and want to differentiate them based on their properties.
+In this example, we will configure a BACnet device to have a dynamic device name based on its `objectName` and `address`
+properties and a dynamic device profile based on its `vendorId` property.
+
+Here is an example configuration snippet for a BACnet device with dynamic device name and profile:
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "YOUR_HOST",
+ "port": 47808,
+ "mask": 24,
+ "objectIdentifier": 599,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "vendorIdentifier": 15,
+ "deviceDiscoveryTimeoutInSec": 5,
+ "devicesDiscoverPeriodSeconds": 30
+ },
+ "devices": [
+ {
+ "host": "*",
+ "port": "*",
+ "pollPeriod": 10000,
+ "deviceInfo": {
+ "deviceNameExpressionSource": "expression",
+ "deviceNameExpression": "${objectName} at ${address}",
+ "deviceProfileExpressionSource": "expression",
+ "deviceProfileExpression": "${vendorId}_profile"
+ },
+ "attributes": [],
+ "timeseries": "*",
+ "attributeUpdates": [],
+ "serverSideRpc": []
+ }
+ ]
+}
+```
+{:.copy-code}
+
+In this configuration:
+- The `deviceNameExpression` is set to `${objectName} at ${address}`, which will create a device name that includes the
+ device's object name and address.
+- The `deviceProfileExpression` is set to `${vendorId}_profile`, which will create a device profile name based on the vendor ID of the device.
+
+After applying this configuration, the device will be created with a name and profile that reflect its specific
+properties. The screenshot below shows how the device appears in ThingsBoard with the dynamic name and profile:
+
+
+
+As you can see, the device name is generated based on the `objectName` and `address`, and the device profile is based
+on the `vendorId`.
+
+Device name/profile dynamic expressions provide flexibility in managing multiple BACnet devices with varying
+configurations and can help in organizing devices effectively within ThingsBoard.
+
+{% capture dynamicDeviceNameProfileExample %}
+You can find full list of available variables in
+the [Advanced configuration](/docs/iot-gateway/config/bacnet/#available-variables-for-device-nameprofile-expressions) section.
+{% endcapture %}
+{% include templates/info-banner.md content=dynamicDeviceNameProfileExample %}
diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/filtering-objects-and-properties.md b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/filtering-objects-and-properties.md
new file mode 100644
index 0000000000..a77e6e9a89
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/filtering-objects-and-properties.md
@@ -0,0 +1,64 @@
+There are situations when a BACnet device has a lot of objects, and you want to read only specific objects or
+properties from the device. You can use filtering options to specify which data should be collected and sent to the
+platform.
+
+Let's look at an example of how to properly configure filtering feature.
+
+In our case, we have a device that have a lot of objects, but we want to read `presentValue` and `units` properties
+from only the first three `Analog Value` objects. In order to do this, we need to configure the filtering options
+in the attributes/timeseries section as shown below:
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "YOUR_HOST",
+ "port": 47808,
+ "mask": "24",
+ "objectIdentifier": 599,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "vendorIdentifier": 15,
+ "deviceDiscoveryTimeoutInSec": 5,
+ "devicesDiscoverPeriodSeconds": 30
+ },
+ "devices": [
+ {
+ "deviceInfo": {
+ "deviceNameExpression": "BACnet Device ${objectName}",
+ "deviceProfileExpression": "default",
+ "deviceNameExpressionSource": "expression",
+ "deviceProfileExpressionSource": "constant"
+ },
+ "altResponsesAddresses": [],
+ "host": "YOUR_DEVICE_HOST",
+ "port": "YOUR_DEVICE_PORT",
+ "pollPeriod": 10000,
+ "attributes": [],
+ "timeseries": [
+ {
+ "key": "${objectName} ${objectType}",
+ "objectType": "analogValue",
+ "objectId": "1-3",
+ "propertyId": ["presentValue", "units"]
+ }
+ ],
+ "attributeUpdates": [],
+ "serverSideRpc": []
+ }
+ ]
+}
+```
+{:.copy-code}
+
+As you can see from the configuration above, we have specified `objectType` as `analogValue`, `objectId` as
+`1-3` (which means we want to read objects with IDs from 1 to 3), and `propertyId` as an array containing
+`presentValue` and `units`. This configuration will ensure that only the specified properties from the selected
+objects are read and sent to the platform. Also, we specified `key` as `${objectName} ${objectType}` to have more
+descriptive telemetry keys.
+
+After saving the changes and starting the connector, you can see that the corresponding device has been added to the
+platform, and its telemetry has started to fill with the filtered data. The screenshot below shows an example of how
+the device telemetry looks like after applying the filtering configuration:
+
+
diff --git a/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/reading-all-device-objects.md b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/reading-all-device-objects.md
new file mode 100644
index 0000000000..8c441f4439
--- /dev/null
+++ b/_includes/templates/iot-gateway/bacnet-connector/examples/time-series-and-attributes/reading-all-device-objects.md
@@ -0,0 +1,54 @@
+There are situations when a BACnet device has a lot of objects, and you want to read all the objects of the device
+without having to manually add each object to the connector configuration. Or maybe you don't know what objects are in
+the device and want to read all the objects automatically. The BACnet connector supports this functionality and allows
+you to read all the objects of the device by easily configuring just one parameter.
+
+Let's look at an example of how to properly configure reading all device objects.
+
+In order to read all the device objects, you need to decide where exactly the values of these objects will be stored:
+in `telemetry` or `attributes`. Depending on this, you need to put `*` in the corresponding section.
+
+In our case, we will store all objects in time series, so the device configuration will look like this:
+
+```json
+{
+ "application": {
+ "objectName": "TB_gateway",
+ "host": "YOUR_HOST",
+ "port": 47808,
+ "objectIdentifier": 599,
+ "vendorIdentifier": 15,
+ "maxApduLengthAccepted": 1476,
+ "segmentationSupported": "segmentedBoth",
+ "deviceDiscoveryTimeoutInSec": 5
+ },
+ "devices": [
+ {
+ "altResponsesAddresses": [],
+ "host": "YOUR_DEVICE_HOST",
+ "port": 47808,
+ "deviceInfo": {
+ "deviceNameExpression": "${objectName}",
+ "deviceProfileExpression": "default",
+ "deviceNameExpressionSource": "expression",
+ "deviceProfileExpressionSource": "constant"
+ },
+ "pollPeriod": 10000,
+ "timeseries": "*",
+ "attributes": [],
+ "attributeUpdates": [],
+ "serverSideRpc": []
+ }
+ ]
+}
+```
+{:.copy-code}
+
+As you can see from the configuration above, we have put `*` in the `timeseries` section, which means that all device
+objects will be saved in the telemetry. In the `attributes` section, we have not put `*`, so the attributes will not
+be read.
+
+After saving the changes and starting the connector, you can see that the corresponding device has been added to the
+platform, and its telemetry has started to fill with all the device objects:
+
+
diff --git a/_includes/templates/iot-gateway/gateway-dashboard-general-conf.md b/_includes/templates/iot-gateway/gateway-dashboard-general-conf.md
index 27687d99a5..516d925733 100644
--- a/_includes/templates/iot-gateway/gateway-dashboard-general-conf.md
+++ b/_includes/templates/iot-gateway/gateway-dashboard-general-conf.md
@@ -1,12 +1,17 @@
-
-
General - this tab contains the main settings, namely:
-- Remote Configuration - enables remote configuration and management of the gateway;
-- Remote Shell - enables remote control of the operating system with the gateway from the Remote Shell widget;
-- ThingsBoard host - hostname or IP address of ThingsBoard server;
-- ThingsBoard port - port of MQTT service on ThingsBoard server;
+- Remote Configuration - enables remote configuration and management of the gateway.
+- Remote Shell - enables remote control of the operating system with the gateway from the Remote Shell widget.
+- Platform host - hostname or IP address of platform server.
+- Platform port - port of MQTT service on platform server.
- Security type (you can read more about them [here](/docs/iot-gateway/configuration/#subsection-security)) - currently 3 types of security are supported for remote configuration:
- - Access Token;
- - TLS + Access Token;
- - Username and Password;
+ - Access Token.
+ - TLS + Access Token.
+ - Username and Password.
- TLS + Private Key (**unsupported yet**).
+- Report strategy (you can read more [here](/docs/iot-gateway/features-overview/report-strategy/)) - strategy for sending gateway status to ThingsBoard:
+ - On report period - sends gateway status after the report period.
+ - On value change - sends gateway status when the value changes.
+ - On value change or report period - sends gateway status when the value changes or report period.
+ - On received - sends gateway status after receiving data from the device (default strategy).
+
+
diff --git a/_includes/templates/iot-gateway/gateway-dashboard-grpc-conf.md b/_includes/templates/iot-gateway/gateway-dashboard-grpc-conf.md
index 0ffc73a42e..f0b311f233 100644
--- a/_includes/templates/iot-gateway/gateway-dashboard-grpc-conf.md
+++ b/_includes/templates/iot-gateway/gateway-dashboard-grpc-conf.md
@@ -1,10 +1,10 @@
-
-
GRPC - provides GRPC configuration:
-- Server port - network port on which the GRPC server will listen for incoming connections;
-- Keep alive permit without calls - allow server to keep the GRPC connection alive even when there are no active RPC calls;
-- Keep alive - duration (in milliseconds) between two successive keepalive ping messages when there is no active RPC call;
-- Max pings without data - maximum number of keepalive ping messages that the server can send without receiving any data before it considers the connection dead;
-- Keep alive timeout - maximum time (in milliseconds) the server should wait for a keepalive ping response before considering the connection dead;
-- Min time between pings - minimum amount of time (in milliseconds) the server should wait between sending keepalive ping messages;
-- Min ping interval without data - minimum amount of time (in milliseconds) the server should wait between sending keepalive ping messages when there is no data being sent or received.
\ No newline at end of file
+- Server port - network port on which the GRPC server will listen for incoming connections.
+- Keep alive permit without calls - allow server to keep the GRPC connection alive even when there are no active RPC calls.
+- Keep alive - duration (in milliseconds) between two successive keepalive ping messages when there is no active RPC call.
+- Max pings without data - maximum number of keepalive ping messages that the server can send without receiving any data before it considers the connection dead.
+- Keep alive timeout - maximum time (in milliseconds) the server should wait for a keepalive ping response before considering the connection dead.
+- Min time between pings - minimum amount of time (in milliseconds) the server should wait between sending keepalive ping messages.
+- Min ping interval without data - minimum amount of time (in milliseconds) the server should wait between sending keepalive ping messages when there is no data being sent or received.
+
+
diff --git a/_includes/templates/iot-gateway/gateway-dashboard-logs-conf.md b/_includes/templates/iot-gateway/gateway-dashboard-logs-conf.md
index fd8715d6cf..c00e4ff78a 100644
--- a/_includes/templates/iot-gateway/gateway-dashboard-logs-conf.md
+++ b/_includes/templates/iot-gateway/gateway-dashboard-logs-conf.md
@@ -1,14 +1,14 @@
-
-
-Logs - a tab for setting local and [remote logs](/docs/iot-gateway/guides/how-to-enable-remote-logging/), which consists of 3 main sections:
+Logs - a tab for setting local and remote logs, which consists of 3 main sections:
- General log settings - the usual settings for the Python [logging](https://docs.python.org/3.8/library/logging.config.html) module are used here:
- - Date format - date format of log message;
+ - Date format - date format of log message.
- Log format - log message format.
- Remote logging - to configure remote logs:
- - Remote logs - enables remote logging and logs reading from the gateway;
+ - Remote logs - enables remote logging and logs reading from the gateway.
- Log level.
- Local logging - for configuring local loggers (Service, Connector, Converter, TB Connection, Storage, Extension):
- - Log level;
- - File path;
- - Log saving period;
+ - Log level - logging level for each local logger: INFO, DEBUG, WARNING, ERROR, CRITICAL, TRACE, NONE.
+ - File path - path to the log folder.
+ - Log saving period.
- Backup count - if **Backup count** is > 0, when a rollover is done, no more than **Backup count** files are kept - the oldest ones are deleted.
+
+
diff --git a/_includes/templates/iot-gateway/gateway-dashboard-other-conf.md b/_includes/templates/iot-gateway/gateway-dashboard-other-conf.md
index c38a88745b..9498469831 100644
--- a/_includes/templates/iot-gateway/gateway-dashboard-other-conf.md
+++ b/_includes/templates/iot-gateway/gateway-dashboard-other-conf.md
@@ -1,10 +1,12 @@
-
-
Other - in this tab, you can configure additional gateway parameters:
- Checking device activity - enables monitoring the activity of each connected device:
- - Inactivity timeout - device inactivity time after which the gateway will disconnect the device;
- - Inactivity check period - periodicity of device activity check.
-- Advanced - configure the following parameters only if you know what you are doing:
- - Min pack send delay - delay between sending packets (Decreasing this setting results in increased CPU usage);
- - QoS - quality of Service in MQTT messaging (0 - at most once, 1 - at least once);
- - Check connectors' configuration - the period of time when the configuration of the connectors will be checked for a change.
\ No newline at end of file
+ - Inactivity timeout (in seconds) - device inactivity time after which the gateway will disconnect the device.
+ - Inactivity check period (in seconds) - periodicity of device activity check.
+- Advanced - additional gateway settings:
+ - Min pack send delay (in milliseconds) - delay between sending packets (Decreasing this setting results in increased CPU usage).
+ - QoS - quality of Service in MQTT messaging (0 - at most once, 1 - at least once).
+ - Check connectors' configuration (in seconds) - the period of time when the configuration of the connectors will be checked for a change.
+ - Max payload size in bytes-defines the largest message the gateway can process at once, ensuring stable performance and preventing oversized data from causing errors.
+ - Min packet size to send-defines the smallest message size the gateway will transmit, preventing the sending of packets that are too small or incomplete.
+
+
diff --git a/_includes/templates/iot-gateway/gateway-dashboard-statistics-conf.md b/_includes/templates/iot-gateway/gateway-dashboard-statistics-conf.md
index ae31c5384c..b879dbd4db 100644
--- a/_includes/templates/iot-gateway/gateway-dashboard-statistics-conf.md
+++ b/_includes/templates/iot-gateway/gateway-dashboard-statistics-conf.md
@@ -1,9 +1,13 @@
-
-
Statistics - in this tab you can configure general statistics, as well as custom statistics:
-- Statistics - enable/disable;
-- Statistic send period - period of time for sending statistics;
+- General statistics - enable/disable gateway statistics (machine, storage, connectors).
+- Custom statistics - enable/disable collecting statistics using custom commands.
+- Statistic send period (in seconds) - period of time for sending statistics.
+- Custom send period (in seconds) - period of time for sending custom statistics.
- Commands - commands for collecting additional statistics (to add a new command, press the **"Add command"** button):
- - Attribute name - gateway telemetry key name;
- - Timeout - timeout for command execution;
- - Command - the result of the command will be used as the value of the client attribute (for example **"/bin/sh -c ipconfig getifaddr en0"**).
\ No newline at end of file
+ - Timeseries name - gateway telemetry key name.
+ - Timeout (in seconds) - timeout for command execution.
+ - Command - the result of the command will be used as the value of the client attribute (for example **"/bin/sh -c ipconfig getifaddr en0"**).
+ - Advanced settings:
+ - Install command - command for installing required packages (for example **"apt-get install -y curl"**).
+
+
diff --git a/_includes/templates/iot-gateway/gateway-dashboard-storage-conf.md b/_includes/templates/iot-gateway/gateway-dashboard-storage-conf.md
index dd93634186..39b34f2d92 100644
--- a/_includes/templates/iot-gateway/gateway-dashboard-storage-conf.md
+++ b/_includes/templates/iot-gateway/gateway-dashboard-storage-conf.md
@@ -1,6 +1,6 @@
-
-
Storage - provides configuration for saving incoming data before it is sent to the platform:
-- Memory storage - saved data to the RAM memory;
-- File storage - saving received data to the hard drive;
-- SQLITE - saved data to the .db file.
\ No newline at end of file
+- [Memory storage](/docs/iot-gateway/configuration/?storageConfig=memory#storage-configuration) - saved data to the RAM memory.
+- [File storage](/docs/iot-gateway/configuration/?storageConfig=file#storage-configuration) - saving received data to the hard drive.
+- [SQLITE](/docs/iot-gateway/configuration/?storageConfig=sqlite#storage-configuration) - saved data to the .db file.
+
+
diff --git a/_includes/templates/iot-gateway/get-set-connector-rpc/modbus.md b/_includes/templates/iot-gateway/get-set-connector-rpc/modbus.md
index c0966a9f90..8eee893aae 100644
--- a/_includes/templates/iot-gateway/get-set-connector-rpc/modbus.md
+++ b/_includes/templates/iot-gateway/get-set-connector-rpc/modbus.md
@@ -22,7 +22,7 @@ get type=16int;functionCode=3;objectsCount=1;address=1;
**Response:**
```json
-{"result": 13}
+{"result":{"value":13}}
```
{:refdef: style="text-align: left;"}
@@ -48,13 +48,13 @@ For example, in our case, we know that we can write 16-bit integer values to the
that contains room light level. To write the value of the register with the address 2, run the following query:
```bash
-set type=16int;functionCode=3;objectsCount=1;address=2;value=80;
+set type=16int;functionCode=6;objectsCount=1;address=2;value=80;
```
**Response:**
```json
-{"result": {"success":true}}
+{"result":{"value":"80"}}
```
{:refdef: style="text-align: left;"}
@@ -70,7 +70,7 @@ get type=16int;functionCode=3;objectsCount=1;address=2;
**Response:**
```json
-{"result": 80}
+{"result":{"value":80}}
```
{:refdef: style="text-align: left;"}
diff --git a/_includes/templates/iot-gateway/get-set-connector-rpc/mqtt.md b/_includes/templates/iot-gateway/get-set-connector-rpc/mqtt.md
index 426b9e85e8..35f40c3526 100644
--- a/_includes/templates/iot-gateway/get-set-connector-rpc/mqtt.md
+++ b/_includes/templates/iot-gateway/get-set-connector-rpc/mqtt.md
@@ -5,6 +5,7 @@ With the GET method you can subscribe to MQTT topic and receive message from it.
```bash
get requestTopicExpression=;responseTopicExpression=;value=;
```
+{: .copy-code}
Where:
- `` - the topic to publish the request;
@@ -18,54 +19,52 @@ To read the value of the room light level, run this query:
```bash
get requestTopicExpression=data/get_light_level;responseTopicExpression=data/response;value=${params};
```
+{: .copy-code}
-**Response:**
-
-```json
-{"result": {"success":true}}
-```
+Also, let's take a look at the data received from the MQTT topic **"data/response"**:
{:refdef: style="text-align: left;"}

{: refdef}
-Also, let's take a look at the data received from the MQTT topic **"data/response"**:
-
-{:refdef: style="text-align: left;"}
-
-{: refdef}
### SET method
With the SET method you can publish a message to MQTT topic.
```bash
-set requestTopicExpression=data/get_light_level;value=${params};
+set requestTopicExpression=data/set_light_level;value=${params};
```
+{: .copy-code}
Where:
- `` - the topic to publish request;
- `` - the value to send.
For example, in our case, we know that we can set the value of the room light level to the MQTT topic
-**"data/light_level"**. To set the value of the room light level, run the following query:
+**"sata/light_level"**. To set the value of the room light level, run the following query:
```bash
set requestTopicExpression=data/set_light_level;value=80;
```
+{: .copy-code}
-**Response:**
-
-```json
-{"result": {"success":true}}
-```
+On the screenshot below, you can see that we have successfully sent the SET request to the MQTT topic **"data/set_light_level"**:
{:refdef: style="text-align: left;"}

{: refdef}
-Also, let's take a look at the result in the **"data/light_level"** MQTT topic:
+Also, let's take a look at the result after SET method in the **"data/light_level"** MQTT topic by sending Two way GET RPC request.
+To read the value of the room light level to make sure the room light level is really updated, run this query:
+
+```bash
+get requestTopicExpression=data/get_light_level;responseTopicExpression=data/response;value=${params};
+```
+{: .copy-code}
+
+On the screenshot below, you can see that the room light level value is updated to 80 after the SET request:
{:refdef: style="text-align: left;"}
-
+
{: refdef}
diff --git a/_includes/templates/iot-gateway/modbus-connector/attributes-and-time-series-subsections-basic.md b/_includes/templates/iot-gateway/modbus-connector/attributes-and-time-series-subsections-basic.md
index 5e5f1e2328..f114d29f5d 100644
--- a/_includes/templates/iot-gateway/modbus-connector/attributes-and-time-series-subsections-basic.md
+++ b/_includes/templates/iot-gateway/modbus-connector/attributes-and-time-series-subsections-basic.md
@@ -32,6 +32,8 @@ For adding a new attribute or time series, use the following steps:
%}
{% include images-gallery.liquid showListImageTitles="true" imageCollection=attributes %}
+##### Report strategy
+
You can enable a specific report strategy for each time series or attribute. This strategy defines how often
data is sent to the ThingsBoard server. The following strategies are available:
@@ -45,6 +47,8 @@ Additional information about the report strategy can be found [here](/docs/iot-g
{% endcapture %}
{% include templates/info-banner.md content=difference %}
+##### Modifier
+
Also, **modifier** for attribute/time series value can be applied using the following settings:
| **Parameter** | **Description** |
@@ -53,4 +57,47 @@ Also, **modifier** for attribute/time series value can be applied using the foll
| Value | The value that will be used to modify the read value |
| --- | |
+{% capture difference %}
+More usage examples can be found in the [Example usage](/docs/iot-gateway/config/modbus/#usage-examples) section.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+

+
+##### Batch reading (Advanced configuration mode only)
+
+To optimize the reading process, you can group multiple registers into a single batch read request. This approach
+reduces the number of requests sent to the Modbus server, which can enhance performance and decrease network traffic.
+Take attention that the registers in a batch read request must be of the same type and function code.
+
+Two parameters are important for group reading configuration: `address` and `tag`. Let's look at them in more detail:
+
+- **address** - is the address of the starting register and the address of the ending register, separated by a `-`
+ character. For example, `0-10` means that the group read starts with the register at address `0` and ends at the
+ register at address `10`, inclusive.
+- **tag** - is a unique identifier for each register within a group read. It is used to identify a specific register within
+ a given address range. The tag name can be formed using an expression using the following variables:
+ - `${address}` - register address within group read.
+ - `${unitId}` - slave ID.
+ - `${functionCode}` - function code.
+ - `${type}` - data type of register.
+ - `${objectsCount}` - number of objects.
+
+Also, `divider` and `multiplier` parameters work as expected.
+
+Example of group reading configuration:
+
+```json
+{
+ "tag": "${unitId} - ${type} - ${address}",
+ "type": "16int",
+ "functionCode": 3,
+ "objectsCount": 1,
+ "address": "0-10"
+}
+```
+
+{% capture difference %}
+More usage examples can be found in the [Example usage](/docs/iot-gateway/config/modbus/#usage-examples) section.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
diff --git a/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/attribute-updates.md b/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/attribute-updates.md
index 9e8681fc9c..38e451091c 100644
--- a/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/attribute-updates.md
+++ b/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/attribute-updates.md
@@ -54,14 +54,16 @@ Now we can check if the attribute update works. Go to "**Entities**" → "**Devi
device → "**Attributes**" tab → select "**Shared attributes**" → click on the "**+**" icon and add `relay` attribute
with type "**Boolean**" set it to "**True**".
-{% assign attributeUpdatesAbsolutePath2 = '
+{% assign attributeUpdates2 = '
===
- image: /images/gateway/modbus-connector/examples/connector-configuration-attribute-updates-3.png,
+ image: /images/gateway/opc-ua-connector/examples/attribute-updates-relative-path-4.png,
===
- image: /images/gateway/opc-ua-connector/examples/connector-configuration-attribute-updates-4.png,
+ image: /images/gateway/opc-ua-connector/examples/attribute-updates-relative-path-5.png,
'
%}
+{% include images-gallery.liquid showListImageTitles="false" imageCollection=attributeUpdates2 %}
+
Now, let’s check the value of the relay register. In the selected device, go to the "**Last telemetry**" tab and
check the value of the `relay` telemetry. It should be `true` since we set the shared attribute to `true`.
diff --git a/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/reserved-rpcs.md b/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/reserved-rpcs.md
index 795fd86e47..2bbf43510c 100644
--- a/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/reserved-rpcs.md
+++ b/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/reserved-rpcs.md
@@ -20,7 +20,7 @@ The server available at `0.0.0.0:5021`. The server has the following structure:
| -------------- | --------------- | ---------- | ---------- |
We are interested in register `1`, which is a coil register. We will use this register to set the value of the
-telemetry parameter. The register is of type `bit`, so we will use `bit` type for the telemetry parameter. The
+telemetry parameter. The register is of type `bits`, so we will use `bits` type for the telemetry parameter. The
configuration for this telemetry will look like this:
```json
@@ -44,7 +44,7 @@ get type=bits;functionCode=1;objectsCount=1;address=1;
Response:
```json
-{"result": false}
+{"result":{"value":false}}
```

@@ -59,29 +59,31 @@ The RPC Debug Terminal is used only for example purpose, so you can use any othe
To set the value of the relay register and turn it on, run the query:
```bash
-set type=bit;functionCode=5;objectsCount=1;address=1;value=1;
+set type=bits;functionCode=5;objectsCount=1;address=1;value=1;
```
Response:
```json
-{"result": {"success":true}}
+{"result":{"value":"1"}}
```
-And as you can see, from the screenshot below, the relay telemetry value has changed to `true`:
+And as you can see, from the screenshot below, the relay telemetry value has changed to `1`:

-Also, let’s check the value of the relay telemetry again:
+Also, let’s check the value of the relay telemetry again: it is `true`
+now because, in the Modbus connector, booleans come from integers — `0` = `false`, `1` = `true`
+(any non-zero is `true`) — so a register value of `1` is reported as `true`.
```bash
-get type=bit;functionCode=3;objectsCount=1;address=1;
+get type=bits;functionCode=3;objectsCount=1;address=1;
```
Response:
```json
-{"result": true}
+{"result":{"value":true}}
```

diff --git a/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/rpc-to-device.md b/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/rpc-to-device.md
index 3887e313f5..d42f8a805d 100644
--- a/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/rpc-to-device.md
+++ b/_includes/templates/iot-gateway/modbus-connector/examples/shared-attributes-rpc/rpc-to-device.md
@@ -86,8 +86,8 @@ Full configuration for Modbus connector for the example above will look like thi
"timeseries": [
{
"tag": "some_key",
- "type": "int16",
- "address": 1,
+ "type": "16int",
+ "address": 0,
"objectsCount": 1,
"functionCode": 3
}
diff --git a/_includes/templates/iot-gateway/modbus-connector/examples/time-series-and-attributes/batch-reading.md b/_includes/templates/iot-gateway/modbus-connector/examples/time-series-and-attributes/batch-reading.md
new file mode 100644
index 0000000000..a4b83ca190
--- /dev/null
+++ b/_includes/templates/iot-gateway/modbus-connector/examples/time-series-and-attributes/batch-reading.md
@@ -0,0 +1,82 @@
+As an example, we will use ThingsBoard Modbus Demo Server, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 5021:5021 thingsboard/tb-gw-modbus-server:latest
+```
+{:.copy-code}
+
+The server available at `0.0.0.0:5021`. The server has the following structure:
+
+| Variable Name | Register Type | Data Type | Address |
+|:---------------|:----------------|------------|:-----------|
+| Temperature | Holding | 16int | 0 |
+| Humidity | Holding | 16int | 1 |
+| Power | Holding | 16int | 2 |
+| Pressure | Holding | 16int | 3 |
+| Relay | Coil | bits | 1 |
+| -------------- | --------------- | ---------- | ---------- |
+
+For optimizing the number of requests sent to the Modbus server, you can use the **Batch reading** feature available
+in the advanced configuration mode. This feature allows reading multiple registers in a single request, which can
+significantly reduce the load on the Modbus server and improve performance.
+
+Let’s look at an example of how to properly configure batch reading to read the `temperature`, `humidity`, `power`,
+and `pressure` registers from the Modbus server.
+
+From the table above, we can see that all the required registers are of the same type (`16int`) and have the same
+function code (`03 - Read Holding Registers`). This means that we can group them into a single batch read request.
+We need to read registers from address `0` to address `3`, so our address range will be `0-3`.
+Also, you need to use, for examples `${address}` variable in the `tag` field to uniquely identify each register within
+the batch read. In our case, we will use the following expression for the `tag` field:
+`${unitId}.${type}.${address}` (you can find more information about variables in the corresponding [section of
+the documentation](/docs/iot-gateway/config/modbus/#batch-reading-advanced-configuration-mode-only)).
+
+Copy and paste the following configuration into the Modbus connector advanced configuration mode:
+
+```json
+{
+ "master": {
+ "slaves": [
+ {
+ "host": "0.0.0.0",
+ "port": 5021,
+ "type": "tcp",
+ "method": "socket",
+ "timeout": 35,
+ "byteOrder": "BIG",
+ "wordOrder": "LITTLE",
+ "retries": true,
+ "retryOnEmpty": true,
+ "retryOnInvalid": true,
+ "pollPeriod": 1000,
+ "unitId": 1,
+ "deviceName": "Demo Device",
+ "deviceType": "default",
+ "sendDataOnlyOnChange": true,
+ "connectAttemptTimeMs": 5000,
+ "connectAttemptCount": 5,
+ "waitAfterFailedAttemptsMs": 300000,
+ "attributes": [],
+ "timeseries": [
+ {
+ "tag": "${unitId}.${type}.${address}",
+ "type": "16int",
+ "functionCode": 3,
+ "objectsCount": 1,
+ "address": "0-3",
+ "divider": 10
+ }
+ ],
+ "attributeUpdates": [],
+ "rpc": []
+ }
+ ]
+ }
+}
+```
+{:.copy-code}
+
+After saving the changes and starting the connector, you see that the corresponding telemetry is being updated
+correctly:
+
+
diff --git a/_includes/templates/iot-gateway/mqtt-connector/attribute-request-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/attribute-request-subsection-advanced.md
deleted file mode 100644
index 7a968f5ec5..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/attribute-request-subsection-advanced.md
+++ /dev/null
@@ -1,51 +0,0 @@
-This section in configuration file looks like:
-```json
-"attributeRequests": [
- {
- "retain": false,
- "topicFilter": "v1/devices/me/attributes/request",
- "deviceInfo": {
- "deviceNameExpressionSource": "message",
- "deviceNameExpression": "${serialNumber}"
- },
- "attributeNameExpressionSource": "message",
- "attributeNameExpression": "${versionAttribute}",
- "topicExpression": "devices/${deviceName}/attrs",
- "valueExpression": "${attributeKey}: ${attributeValue}"
- }
-]
-```
-{: .copy-code}
-
-Also, you can request multiple attributes at once. Simply add one more JSON-path to
-attributeNameExpression parameter. For example, we want to request two shared attributes in one request, our config
-will look like:
-```json
-"attributeRequests": [
- {
- "retain": false,
- "topicFilter": "v1/devices/me/attributes/request",
- "deviceInfo": {
- "deviceNameExpressionSource": "message",
- "deviceNameExpression": "${serialNumber}"
- },
- "attributeNameExpressionSource": "message",
- "attributeNameExpression": "${versionAttribute}, ${pduAttribute}",
- "topicExpression": "devices/${deviceName}/attrs",
- "valueExpression": "${attributeKey}: ${attributeValue}"
- }
-]
-```
-
-
-
-| **Parameter** | **Default value** | **Description** |
-|:--------------------------|:-|-
-| retain | **false** | If set to true, the message will be set as the "last known good"/retained message for the topic. |
-| topicFilter | **v1/devices/me/attributes/request** | Topic for attribute request |
-| deviceNameExpression | **${serialNumber}** | JSON-path expression, for looking the device name in topicFilter message |
-| attributeNameExpression | **${versionAttribute}** | JSON-path expression, for looking the attribute name in topicFilter message |
-| topicExpression | **devices/${deviceName}/attrs** | JSON-path expression, for formatting reply topic |
-| valueExpression | **${attributeKey}: ${attributeValue}** | Message that will be sent to topic from topicExpression |
-| ---
-
diff --git a/_includes/templates/iot-gateway/mqtt-connector/attribute-request-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/attribute-request-subsection-basic.md
index c9d4a3afe8..4258293ab9 100644
--- a/_includes/templates/iot-gateway/mqtt-connector/attribute-request-subsection-basic.md
+++ b/_includes/templates/iot-gateway/mqtt-connector/attribute-request-subsection-basic.md
@@ -1,4 +1,18 @@
-To adding new requests mapping, navigate to the "Requests mapping" tab and click the "plus" icon.
-In the open modal window, select the "Attribute request" type, set a topic filter. Fill in the fields of the "Input request parsing" and "Output request parsing" sections. Then, click "Add".
+In order to add new attribute request mapping, follow these steps:
-
\ No newline at end of file
+{% assign AttributesRequest = '
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-11-ce.png,
+ title: Click the "**Add mapping**" under "**Requests mapping**" section to add new attribute request mapping.
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-attribute-requests-1.png,
+ title: Select "**Attribute request**" in the **Request type** field, enter the "**Topic filter**"
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-attribute-requests-2.png,
+ title: Configure the **Device name expression**, **Response topic expression**, and **Attribute name expression** fields.
+ Select the source type for each field (`Message`, `Topic`, or `Constant`) and enter the corresponding values.
+ You can also set the **Retain** option to determine whether the attribute response message should be retained by the MQTT broker.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=AttributesRequest %}
diff --git a/_includes/templates/iot-gateway/mqtt-connector/attribute-updates-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/attribute-updates-subsection-advanced.md
deleted file mode 100644
index c3495a6ff7..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/attribute-updates-subsection-advanced.md
+++ /dev/null
@@ -1,24 +0,0 @@
-This section in configuration file looks like:
-
-```json
- "attributeUpdates": [
- {
- "retain": false,
- "deviceNameFilter": ".*",
- "attributeFilter": "firmwareVersion",
- "topicExpression": "sensor/${deviceName}/${attributeKey}",
- "valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}"
- }
- ]
-```
-
-
-
-| **Parameter** | **Default value** | **Description** |
-|:-|:----------------------------------------------------|--------------------------------------------------------------------------------------------------
-| retain | **false** | If set to true, the message will be set as the "last known good"/retained message for the topic. |
-| deviceNameFilter | **.\*** | Regular expression device name filter, used to determine, which function to execute. |
-| attributeFilter | **uploadFrequency** | Regular expression attribute name filter, used to determine, which function to execute. |
-| topicExpression | **sensor/${deviceName}/${attributeKey}** | JSON-path expression used for creating topic address to send a message. |
-| valueExpression | **{\\"${attributeKey}\\":\\"${attributeValue}\\"}** | JSON-path expression used for creating the message data that will send to topic. |
-|---
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/attribute-updates-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/attribute-updates-subsection-basic.md
index a14b6d5176..9011625d53 100644
--- a/_includes/templates/iot-gateway/mqtt-connector/attribute-updates-subsection-basic.md
+++ b/_includes/templates/iot-gateway/mqtt-connector/attribute-updates-subsection-basic.md
@@ -1,4 +1,17 @@
-To adding new requests mapping, navigate to the "Requests mapping" tab and click the "plus" icon.
-In the open modal window, select the "Attribute update" type, and set a device name filter, attribute filter, response value expression, and response topic expression. Then, click “Add”.
+In order to add new attribute update mapping, follow these steps:
-
\ No newline at end of file
+{% assign AttributesUpdate = '
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-11-ce.png,
+ title: Click the "**Add mapping**" under "**Requests mapping**" section to add new attribute request mapping.
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-attribute-updates-1.png,
+ title: Select "**Attribute update**" in the **Request type** field, enter the "**Device name filter**"
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-attribute-updates-2.png,
+ title: Configure the **Attribute filter**, **Response value expression**, and **Response topic expression** fields.
+ You can also set the **Retain** option to determine whether the attribute response message should be retained by the MQTT broker.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=AttributesUpdate %}
diff --git a/_includes/templates/iot-gateway/mqtt-connector/connect-request-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/connect-request-subsection-advanced.md
deleted file mode 100644
index 8fd8defc37..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/connect-request-subsection-advanced.md
+++ /dev/null
@@ -1,47 +0,0 @@
-This section in configuration looks like:
-```json
-"connectRequests": [
- {
- "topicFilter": "sensor/connect",
- "deviceInfo": {
- "deviceNameExpressionSource": "message",
- "deviceNameExpression": "${serialNumber}",
- "deviceProfileExpressionSource": "constant",
- "deviceProfileExpression": "Thermometer"
- }
- }
-]
-```
-{: .copy-code}
-
-
-
-**Device name from the message body:**
-
-| **Parameter** | **Default value** | **Description** |
-|:----------------------|:-------------------------------------|:---------------------------------------------------------------------------------------------|
-| topicFilter | **sensor/connect** | Topic address on the broker, where the broker sends information about new connected devices. |
-| deviceNameExpression | **${serialNumber}** | JSON-path expression, for looking the new device name. |
-| ---
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/connect" -m '{"serialNumber":"SN-001"}'
-```
-{: .copy-code}
-
-**Device name from the topic:**
-
-| **Parameter** | **Default value** | **Description** |
-|:--------------------------|:-------------------------------------|:---------------------------------------------------------------------------------------------|
-| topicFilter | **sensor/+/connect** | Topic address on the broker, where the broker sends information about new connected devices. |
-| deviceNameTopicExpression | **(?<=sensor\/)(.\*?)(?=\/connect)** | Regular expression for looking the device name in topic path. |
-| ---
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/SN-001/connect" -m ''
-```
-{: .copy-code}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/connect-request-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/connect-request-subsection-basic.md
deleted file mode 100644
index 88355bad50..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/connect-request-subsection-basic.md
+++ /dev/null
@@ -1,24 +0,0 @@
-To adding new requests mapping, navigate to the "Requests mapping" tab and click the "plus" icon.
-In the open modal window, select the "Connect request" type, set a topic filter, and fill in the "Name" and "Profile name" fields of the "Device" section. Then, click "Add".
-
-**Device name from the message body:**
-
-
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/connect" -m '{"serialNumber":"SN-001"}'
-```
-{: .copy-code}
-
-**Device name from the topic:**
-
-
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/SN-001/connect" -m ''
-```
-{: .copy-code}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/connection-to-broker-advanced-section.md b/_includes/templates/iot-gateway/mqtt-connector/connection-to-broker-advanced-section.md
deleted file mode 100644
index e45aab49cc..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/connection-to-broker-advanced-section.md
+++ /dev/null
@@ -1,29 +0,0 @@
-This configuration section contains settings of the connection to broker, such as:
-
-| **Parameter** | **Default value** | **Description** |
-|:--------------|:-------------------------|--------------------------------------------------------------------
-| name | **Default Local Broker** | Broker name for logs and saving to persistent devices. |
-| host | **127.0.0.1** | MQTT broker hostname or ip address. |
-| port | **1883** | MQTT port on the broker. |
-| version | **5** | MQTT protocol version may be 3 (3.1), 4(3.11) or 5(5) |
-| clientId | **tb_gw_li06e** | This is the client ID. It must be unique for each session. |
-| security | **anonymous** | This is the configuration for client authorization at MQTT Broker. |
-| ---
-
-Example:
-
-```json
-"broker": {
- "name": "Default Local Broker",
- "host": "127.0.0.1",
- "port": 1883,
- "version": 5,
- "clientId": "tb_gw_li06e",
- "security": {
- "type": "anonymous"
- }
-},
-```
-{: .copy-code}
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/connection-to-broker-basic-section.md b/_includes/templates/iot-gateway/mqtt-connector/connection-to-broker-basic-section.md
deleted file mode 100644
index b9efb48b2e..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/connection-to-broker-basic-section.md
+++ /dev/null
@@ -1,9 +0,0 @@
-This configuration section contains settings of the connection to broker, such as:
-
-- Host - MQTT broker hostname or ip address;
-- Port - MQTT port on the broker;
-- MQTT version - MQTT protocol version;
-- Client ID - this is the client ID. It must be unique for each session;
-- Security - configuration for client authorization at MQTT Broker (anonymous, basic, or certificates).
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-bytes-config.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-bytes-config.md
deleted file mode 100644
index 9cf8e4dd15..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-bytes-config.md
+++ /dev/null
@@ -1,60 +0,0 @@
-Bytes converter is the default converter, it looks for '**deviceName**', '**deviceType**', attributes and telemetry in the incoming
-message from the broker, following the rules described in this subsection:
-
-| **Parameter** | **Default value** | **Description** |
-|:------------------------|:------------------|------------------------------------------------------------------------------------------------------------------|
-| type | **bytes** | Provides information to connector that default converter is to be used for converting data from topic. |
-| deviceNameExpression | **[0:4]** | The expression that is used to find device name in the incoming message. |
-| deviceProfileExpression | **[1:3]** | The expression that is used to find device type in the incoming message. |
-| timeout | **60000** | Timeout for triggering "Device Disconnected" event. |
-| attributes: | | This subsection contains parameters of the incoming message, to be interpreted as attributes for the device. |
-| ... type | **raw** | Type of incoming data for a current attribute. |
-| ... key | **temp** | Attribute name, to be sent to ThingsBoard instance. |
-| ... value | **[:]** | Final view of data that will be sent to ThingsBoard, [:] - will replace to device data using python slice rules. |
-| timeseries: | | This subsection contains parameters of the incoming message, to be interpreted as telemetry for the device. |
-| ... type | **raw** | Type of incoming data for a current telemetry. |
-| ... key | **rawData** | Telemetry name, to be sent to ThingsBoard instance. |
-| ... value | **[4:]** | Final view of data that will be sent to ThingsBoard, [:] - will replace to device data using python slice rules. |
-| ---
-
-{% capture difference %}
-**Parameters in attributes and telemetry section may differ from those presented above, but will have the same structure.**
-{% endcapture %}
-{% include templates/info-banner.md content=difference %}
-
-**Note**: The device profile is set when the device is created. Changing the device profile using a Gateway is not supported.
-
-Mapping subsection will look like:
-```json
-{
- "topicFilter": "sensor/raw_data",
- "subscriptionQos": 1,
- "converter": {
- "type": "bytes",
- "deviceInfo": {
- "deviceNameExpressionSource": "message",
- "deviceNameExpression": "[0:4]",
- "deviceProfileExpressionSource": "constant",
- "deviceProfileExpression": "default"
- },
- "sendDataOnlyOnChange": false,
- "timeout": 60000,
- "attributes": [
- {
- "type": "raw",
- "key": "rawData",
- "value": "[:]"
- }
- ],
- "timeseries": [
- {
- "type": "raw",
- "key": "temp",
- "value": "[4:]"
- }
- ]
- }
-}
-```
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-custom-config.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-custom-config.md
deleted file mode 100644
index b221a46e17..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-custom-config.md
+++ /dev/null
@@ -1,35 +0,0 @@
-A custom converter is converter written for some device:
-
-| **Parameter** | **Default value** | **Description** |
-|:------------------|:------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| type | **custom** | Provides information to connector that a custom converter will be used for converting data from the topic. |
-| extension | **CustomMqttUplinkConverter** | Name of custom converter class. |
-| extension-config | | This subsection is a configuration for the custom converter. In default example it contains the number of bytes and keys for telemetry. |
-| temperatureBytes | **2** | In the default example, first 2 bytes from received message will be interpreted as **temperature** key of telemetry (Substring "Bytes" will remove if exists). |
-| humidityBytes | **2** | In the default example, the second and third byte from received message will be interpreted as **humidity** key of telemetry (Substring "Bytes" will remove if exists). |
-| batteryLevelBytes | **1** | In the default example, the fifth byte from received message will be interpreted as **batteryLevel** key of telemetry (Substring "Bytes" will removed if exists). |
-| ---
-
-{% capture difference %}
-**All parameters from this subsection and topic will be transferred as dictionary during initialization to the converter object.**
-{% endcapture %}
-{% include templates/info-banner.md content=difference %}
-
-
-Converter subsection in the configuration will look like:
-```json
-"topicFilter": "custom/sensors/+",
- "subscriptionQos": 1,
- "converter": {
- "type": "custom",
- "extension": "CustomMqttUplinkConverter",
- "cached": true,
- "extensionConfig": {
- "temperature": 2,
- "humidity": 2,
- "batteryLevel": 1
- }
- }
-```
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-json-config.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-json-config.md
deleted file mode 100644
index f533f3b565..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-json-config.md
+++ /dev/null
@@ -1,140 +0,0 @@
-Json converter is the default converter, it looks for '**deviceName**', '**deviceType**', attributes and telemetry in
-the incoming message from the broker, following the rules described in this subsection:
-
-| **Parameter** | **Default value** | **Description** |
-|:------------------------|:----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| type | **json** | Provides information to connector that default converter is to be used for converting data from topic. |
-| deviceNameExpression | **${serialNumber}** | Simple JSON expression, is used for looking up device name in the incoming message (parameter "serialNumber" will be used as the device name). |
-| deviceProfileExpression | **${sensorType}** | Simple JSON expression, is used for looking up device type in the incoming message (parameter "sensorType" will be used as the device type). |
-| timeout | **60000** | Timeout for triggering "Device Disconnected" event |
-| attributes: | | This subsection contains parameters of the incoming message, to be interpreted as attributes for the device. |
-| ... type | **string** | Type of incoming data for a current attribute. |
-| ... key | **model** | Attribute name, to be sent to ThingsBoard instance. |
-| ... value | **${sensorModel}** | Simple JSON expression, is used for looking up value in the incoming message, to be sent to ThingsBoard instance as the value of key parameter. |
-| | | |
-| ... type | **string** | Type of incoming data for a current attribute. |
-| ... key | **${sensorModel}** | Simple JSON expression, is used for looking up value in the incoming message, to be used as attribute name. |
-| ... value | **on** | Attribute value, to be sent to ThingsBoard instance. |
-| timeseries: | | This subsection contains parameters of the incoming message, to be interpreted as telemetry for the device. |
-| ... type | **integer** | Type of incoming data for a current telemetry. |
-| ... key | **temperature** | Telemetry name, to be sent to ThingsBoard instance. |
-| ... value | **${temp}** | Simple JSON expression, is used for looking up value in the incoming message, to be sent to ThingsBoard instance as the value of key parameter. |
-| | | |
-| ... type | **integer** | Type of incoming data for a current telemetry. |
-| ... key | **humidity** | Telemetry name, to be sent to ThingsBoard instance. |
-| ... value | **${hum}** | Simple JSON expression, is used for looking up value in the incoming message, to be sent to ThingsBoard instance as the value of key parameter. |
-| ... tsField | **${timestampField}** | **Optional.** JSON-path expression for field that carries a datetime string. If not present, the `ts` or `timestamp` properties from incoming message will be used as timestamp for data entry. |
-| ... dayfirst | **false** | **Optional.** Points out that the first number is the **day** (`DD.MM.YY HH:mm:ss.SSS`). • `false` → `10.11.24 10:10:10.252` → **11 Oct 2024 10:10:10.252** • `true` → `10.11.24 10:10:10.252` → **10 Nov 2024 10:10:10.252** |
-| ... yearfirst | **false** | **Optional.** Points out that the first number is the **year** (`DD.MM.YY HH:mm:ss.SSS`). • `false` → follows `dayfirst` rule • `true` → `10.11.24 10:10:10.252` → **24 Nov 2010 10:10:10.252** |
-| ---
-
-{% capture difference %}
-**Parameters in attributes and telemetry section may differ from those presented above, but will follow the same
-structure.**
-{% endcapture %}
-{% include templates/info-banner.md content=difference %}
-
-{% capture difference %}
-**Note**: The device profile is set when the device is created. Changing the device profile using a Gateway is not
-supported.
-{% endcapture %}
-{% include templates/info-banner.md content=difference %}
-
-**Mapping subsection for Example 1 will look like:**
-
-```json
-{
- "topicFilter": "sensor/data",
- "subscriptionQos": 1,
- "converter": {
- "type": "json",
- "deviceInfo": {
- "deviceNameExpressionSource": "message",
- "deviceNameExpression": "${serialNumber}",
- "deviceProfileExpressionSource": "message",
- "deviceProfileExpression": "${sensorType}"
- },
- "sendDataOnlyOnChange": false,
- "timeout": 60000,
- "attributes": [
- {
- "type": "string",
- "key": "model",
- "value": "${sensorModel}"
- },
- {
- "type": "string",
- "key": "${sensorModel}",
- "value": "on"
- }
- ],
- "timeseries": [
- {
- "type": "string",
- "key": "temperature",
- "value": "${temp}"
- },
- {
- "type": "double",
- "key": "humidity",
- "value": "${hum}",
- "tsField": "${timestampField}",
- "dayfirst": true
- },
- {
- "type": "string",
- "key": "combine",
- "value": "${hum}:${temp}"
- }
- ]
- }
-}
-```
-
-
-
-{% capture tsField %}
-**Note**: In **Example 1** configuration section for `humidity` timeseries key illustrates how to use the `tsField` and
-`dayfirst` options.
-{% endcapture %}
-{% include templates/info-banner.md content=tsField %}
-
-**Mapping for Example 2 will look like:**
-
-```json
-"topicFilter": "sensor/+/data",
- "subscriptionQos": 1,
- "converter": {
- "type": "json",
- "deviceInfo": {
- "deviceNameExpressionSource": "topic",
- "deviceNameExpression": "(?<=sensor/)(.*?)(?=/data)",
- "deviceProfileExpressionSource": "constant",
- "deviceProfileExpression": "Thermometer"
- },
- "sendDataOnlyOnChange": false,
- "timeout": 60000,
- "attributes": [
- {
- "type": "string",
- "key": "model",
- "value": "${sensorModel}"
- }
- ],
- "timeseries": [
- {
- "type": "double",
- "key": "temperature",
- "value": "${temp}"
- },
- {
- "type": "string",
- "key": "humidity",
- "value": "${hum}"
- }
- ]
- }
-}
-```
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-advanced.md
deleted file mode 100644
index 51416f2c39..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-advanced.md
+++ /dev/null
@@ -1,59 +0,0 @@
-Now select the payload type:
-
-{% capture mqttconvertertypespec %}
-JSONRecommended if json will be received in response%,%json%,%templates/iot-gateway/mqtt-connector/data-conversion-json-config.md%br%
-BytesRecommended if bytes will be received in response%,%bytes%,%templates/iot-gateway/mqtt-connector/data-conversion-bytes-config.md%br%
-CustomRecommended if bytes or anything else will be received in response%,%custom%,%templates/iot-gateway/mqtt-connector/data-conversion-custom-config.md{% endcapture %}
-
-{% include content-toggle.liquid content-toggle-id="MqttConverterTypeConfig" toggle-spec=mqttconvertertypespec %}
-
-{% capture difference %}
-**Note**: You can specify multiple mapping objects inside the array.{% endcapture %}
-{% include templates/info-banner.md content=difference %}
-
-Also, you can combine values from MQTT message in attributes, telemetry and serverSideRpc section, for example:
-{% highlight json %}
-{
- {
- "topicFilter": "sensor/data",
- "subscriptionQos": 1,
- "converter": {
- "type": "json",
- "deviceInfo": {
- "deviceNameExpressionSource": "message",
- "deviceNameExpression": "${serialNumber}",
- "deviceProfileExpressionSource": "message",
- "deviceProfileExpression": "${sensorType}"
- "timeout": 60000,
- "attributes": [],
- "timeseries": [
- {
- "type": "integer",
- "key": "temperature",
- "value": "${temp}"
- },
- {
- "type": "integer",
- "key": "humidity",
- "value": "${hum}"
- },
- {
- "type": "string",
- "key": "combine",
- "value": "${hum}:${temp}"
- }
- ]
- }
- }
-}
-{% endhighlight %}
-
-Mapping process subscribes to the MQTT topics using **topicFilter** parameter of the mapping object.
-Each message that is published to this topic by other devices or applications is analyzed to extract device name, type and data (attributes and/or timeseries values).
-By default, gateway uses Json converter, but it is possible to provide custom converter. See examples in the source code.
-
-{% capture difference %}
-**Connector won't pass the '**None**' value from the converter**
-{% endcapture %}
-{% include templates/info-banner.md content=difference %}
-
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-basic.md
deleted file mode 100644
index 8f7d010174..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-basic.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Now select the payload type:
-
-{% capture mqttconnectordataconversionsubsection %}
-JSONRecommended if json will be received in response%,%json%,%templates/iot-gateway/mqtt-connector/data-conversion-subsection-json.md%br%
-BytesRecommended if bytes will be received in response%,%bytes%,%templates/iot-gateway/mqtt-connector/data-conversion-subsection-bytes.md%br%
-CustomRecommended if bytes or anything else will be received in response%,%custom%,%templates/iot-gateway/mqtt-connector/data-conversion-subsection-custom.md{% endcapture %}
-
-{% include content-toggle.liquid content-toggle-id="mqttconnectordataconversionsubsection" toggle-spec=mqttconnectordataconversionsubsection %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-bytes.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-bytes.md
deleted file mode 100644
index 450213f364..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-bytes.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Converter for this payload type designed for binary MQTT payloads, this converter directly interprets binary data to retrieve device names and device profile names, along with attributes and time series, using specific byte positions for data extraction.
-
-{% assign dataConversionBasicBytesSubsection = '
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-bytes-subsection-1-ce.png,
- title: Select "Bytes" payload type, and fill in the fields in the "Device" section. Then click "pencil" icon of the "Attributes" section to add new attribute key;
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-bytes-subsection-2-ce.png,
- title: In the opened window click "Add attribute". Enter the key name, select the type and enter the value of the key. Click "Apply";
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-bytes-subsection-3-ce.png,
- title: Now click on the "pencil" icon of the "Time series" section to add new time series key;
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-bytes-subsection-4-ce.png,
- title: In the opened window click "Add time series". Enter the key name, select the type and enter the value of the key. Click "Apply";
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-bytes-subsection-5-ce.png,
- title: Click "Add".
-'
-%}
-
-{% include images-gallery.liquid showListImageTitles="true" imageCollection=dataConversionBasicBytesSubsection %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-custom.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-custom.md
deleted file mode 100644
index 90f7fac16f..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-custom.md
+++ /dev/null
@@ -1,18 +0,0 @@
-This option allows you to use a custom converter for specific data tasks.
-You need to add your custom converter to the extension folder and enter its class name in the UI settings.
-Any keys you provide will be sent as configuration to your custom converter.
-
-{% assign dataConversionBasicCustomSubsection = '
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-custom-subsection-1-ce.png,
- title: Select "Custom" payload type, and fill in the fields in the "Device" section. Then click "pencil" icon of the "Keys" section to add new key;
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-custom-subsection-2-ce.png
- title: In the opened window click "Add key". Enter the key name and its value. Click "Apply";
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-custom-subsection-3-ce.png
- title: Click "Add".
-'
-%}
-
-{% include images-gallery.liquid showListImageTitles="true" imageCollection=dataConversionBasicCustomSubsection %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-json.md b/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-json.md
deleted file mode 100644
index b6ca5e3193..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-conversion-subsection-json.md
+++ /dev/null
@@ -1,24 +0,0 @@
-Converter for this payload type processes MQTT messages in JSON format.
-It uses JSON Path expressions to extract vital details such as device names, device profile names, attributes, and time series from the message.
-And regular expressions to get device details from topics.
-
-{% assign dataConversionBasicJsonSubsection = '
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-json-subsection-1-ce.png,
- title: Select "JSON" payload type, and fill in the fields in the "Device" section. Then click "pencil" icon of the "Attributes" section to add new attribute key;
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-json-subsection-2-ce.png,
- title: In the opened window click "Add attribute". Enter the key name, select the type and enter the value of the key. Click "Apply";
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-json-subsection-3-ce.png,
- title: Now click on the "pencil" icon of the "Time series" section to add new time series key;
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-json-subsection-4-ce.png,
- title: In the opened window click "Add time series". Enter the key name, select the type and enter the value of the key. Click "Apply";
- ===
- image: /images/gateway/mqtt-connector/data-conversion-basic-json-subsection-5-ce.png,
- title: Click "Add".
-'
-%}
-
-{% include images-gallery.liquid showListImageTitles="true" imageCollection=dataConversionBasicJsonSubsection %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-mapping-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/data-mapping-subsection-advanced.md
deleted file mode 100644
index 25f1e43de5..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-mapping-subsection-advanced.md
+++ /dev/null
@@ -1,13 +0,0 @@
-| **Parameter** | **Default value** | **Description** |
-|:---------------|:------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| topicFilter | **sensor/data** | Topic address for subscribing. |
-| QoS | **1** | An agreement between the message sender and receiver that defines the level of delivery guarantee for a specific message. (0-At most once, 1-At least once, 2-Exactly once) |
-| ---
-
-The **topicFilter** supports special symbols: '#' and '+', allowing to subscribe to multiple topics.
-
-Also, MQTT connector supports shared subscriptions.
-To create shared subscription you need to add "**$share/**" as a prefix for topic filter and shared subscription group name.
-For example to subscribe to the *my-shared-topic* in group ***my-group-name*** you can set the topic filter to "$share/***my-group-name***/*my-shared-topic*".
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/data-mapping-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/data-mapping-subsection-basic.md
deleted file mode 100644
index fbdd0eebcc..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/data-mapping-subsection-basic.md
+++ /dev/null
@@ -1,15 +0,0 @@
-For adding new data mapping, click the "plus" icon:
-
-
-
-Opened modal window provide the following fields: topic filter, QoS, payload type:
-
-
-
-The **Topic filter** - topic address for subscribing. The **Topic filter** supports special symbols: '#' and '+', allowing to subscribe to multiple topics.
-
-Also, MQTT connector supports shared subscriptions.
-To create shared subscription you need to add "**$share/**" as a prefix for topic filter and shared subscription group name.
-For example to subscribe to the *my-shared-topic* in group ***my-group-name*** you can set the topic filter to "$share/***my-group-name***/*my-shared-topic*".
-
-**MQTT Quality of Service** (QoS) is an agreement between the message sender and receiver that defines the level of delivery guarantee for a specific message. (0-At most once, 1-At least once, 2-Exactly once)
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/device-connect-request-basic-section.md b/_includes/templates/iot-gateway/mqtt-connector/device-connect-request-basic-section.md
new file mode 100644
index 0000000000..852ae60401
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/device-connect-request-basic-section.md
@@ -0,0 +1,15 @@
+In order to add new connect request mapping, follow these steps:
+
+{% assign ConnectRequest = '
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-11-ce.png,
+ title: Click the “**Add mapping**” under “**Requests mapping**” section to add new connect request mapping.
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-12-ce.png,
+ title: Select "**Connect request**" in the **Request type** field, enter the "**Topic filter**", and select source
+ type for **Name** and **Profile name** fields (`Message`, `Constant`, or `Topic`). Enter the corresponding
+ value which can be [json path](/docs/iot-gateway/config/mqtt/#json-path), [regex](/docs/iot-gateway/config/mqtt/#regular-expressions), or constant value based on the selected source type.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=ConnectRequest %}
diff --git a/_includes/templates/iot-gateway/mqtt-connector/device-rpc-basic-section.md b/_includes/templates/iot-gateway/mqtt-connector/device-rpc-basic-section.md
new file mode 100644
index 0000000000..fe678d3b0b
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/device-rpc-basic-section.md
@@ -0,0 +1,19 @@
+In order to add a new RPC method, follow these steps:
+
+{% assign creatingRPC = '
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-11-ce.png,
+ title: Click the "**Add mapping**" under "**Requests mapping**" section to add new server side rpc command.
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-rpc-overview-1.png,
+ title: Choose the "**Request type**": `With response` or `Without response`.
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-rpc-overview-3.png,
+ title: Fill in the required fields - "**Device name filter**", "**Method filter**", "**Request topic expression**", and "**Value expression**".
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-rpc-overview-2.png,
+ title: For two-way RPC, also configure "**Response topic expression**", "**Response topic QoS**", and "**Response timeout**". Click "**Add**" when done.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=creatingRPC %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/disconnect-request-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/disconnect-request-subsection-advanced.md
deleted file mode 100644
index 8ac9da378b..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/disconnect-request-subsection-advanced.md
+++ /dev/null
@@ -1,53 +0,0 @@
-This section in configuration file looks like:
-
-```json
-"disconnectRequests": [
- {
- "topicFilter": "sensor/disconnect",
- "deviceInfo": {
- "deviceNameExpressionSource": "message",
- "deviceNameExpression": "${serialNumber}"
- }
-},
- {
- "topicFilter": "sensor/+/disconnect",
- "deviceInfo": {
- "deviceNameExpressionSource": "topic",
- "deviceNameExpression": "(?<=sensor/)(.*?)(?=/connect)"
- }
- }
-]
-```
-{: .copy-code}
-
-
-
-**Name in a message from broker:**
-
-| **Parameter** | **Default value** | **Description** |
-|:-|:-------------------------------------|-
-| topicFilter | **sensor/disconnect** | Topic address on the broker, where the broker sends information about disconnected devices. |
-| deviceNameExpression | **${serialNumber}** | JSON-path expression, for looking the new device name. |
-|---
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/disconnect" -m '{"serialNumber":"SN-001"}'
-```
-{: .copy-code}
-
-**Name in topic address:**
-
-| **Parameter** | **Default value** | **Description** |
-|:-|:-------------------------------------|-
-| topicFilter | **sensor/+/disconnect** | Topic address on the broker, where the broker sends information about disconnected devices. |
-| deviceNameTopicExpression | **(?<=sensor\/)(.\*?)(?=\/connect)** | Regular expression for looking the device name in topic path. |
-|---
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/SN-001/disconnect" -m ''
-```
-{: .copy-code}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/disconnect-request-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/disconnect-request-subsection-basic.md
index df42cb1aca..754607b12a 100644
--- a/_includes/templates/iot-gateway/mqtt-connector/disconnect-request-subsection-basic.md
+++ b/_includes/templates/iot-gateway/mqtt-connector/disconnect-request-subsection-basic.md
@@ -1,24 +1,15 @@
-To adding new requests mapping, navigate to the "Requests mapping" tab and click the "plus" icon.
-In the open modal window, select the "Disconnect request" type, set a topic filter, and fill in the "Name" field of the "Device" section. Then, click "Add".
-
-**Name in a message from broker:**
-
-
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/disconnect" -m '{"serialNumber":"SN-001"}'
-```
-{: .copy-code}
-
-**Name in topic address:**
-
-
-
-In this case the following messages are valid:
-
-```bash
-mosquitto_pub -h YOUR_MQTT_BROKER_HOST -p YOUR_MQTT_BROKER_PORT -t "sensor/SN-001/disconnect" -m ''
-```
-{: .copy-code}
\ No newline at end of file
+In order to add new disconnect request mapping, follow these steps:
+
+{% assign DisconnectRequest = '
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-11-ce.png,
+ title: Click the "**Add mapping**" under "**Requests mapping**" section to add new disconnect request mapping.
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-disconnect-configuring-12-ce.png,
+ title: Select "**Disconnect request**" in the **Request type** field, enter the "**Topic filter**", and select source
+ type for **Name** field (`Message`, `Topic`, or `Constant`). Enter the corresponding
+ value which can be [json path](/docs/iot-gateway/config/mqtt/#json-path), [regex](/docs/iot-gateway/config/mqtt/#regular-expressions), or constant value based on the selected source type.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=DisconnectRequest %}
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/attribute-request.md b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/attribute-request.md
new file mode 100644
index 0000000000..de507104f7
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/attribute-request.md
@@ -0,0 +1,161 @@
+For an Attribute request, the gateway must know which device name to target and which attribute to request. You can extract the device name either from the `Message` payload using [json-path](/docs/iot-gateway/config/mqtt/#json-path)
+or from the topic using a [regex](/docs/iot-gateway/config/mqtt/#regular-expressions). Choose [json-path](/docs/iot-gateway/config/mqtt/#json-path) when the device name is inside the JSON message; choose [regex](/docs/iot-gateway/config/mqtt/#regular-expressions) when it's encoded in the topic.
+
+Suppose you want to retrieve the current firmware version for device `SN-001` from ThingsBoard to make decisions based on the firmware version.
+
+{% capture difference %}
+**Please note:**
+An **Attribute request** allows a device to retrieve attribute values from ThingsBoard. This is useful for:
+- Getting configuration parameters stored as shared attributes
+- Retrieving client attributes that were previously reported
+- Implementing device configuration management
+
+The gateway acts as a bridge, receiving the attribute request from the device, fetching the attribute from ThingsBoard, and delivering the response back to the device.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+Let's configure an Attribute request in the MQTT connector to allow devices to request attribute values from ThingsBoard.
+We'll demonstrate two ways to extract the device name:
+
+- From message (`JSON` payload).
+- From topic (e.g., `sensor/SN-001/attributes/request`).
+
+Follow these steps:
+
+{% assign deviceNameAttributeJson = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" - "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-gateway.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/mqtt-gateway-configuring-11-ce.png,
+ title: Select the MQTT connector, click on the "**Basic**". Click the "**Add mapping**" under "**Requests mapping**" section to add new attribute request mapping.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attribute-request-1.png,
+ title: Select "**Attribute request**" in the **Request type** field, enter the "**Topic filter**" as `v1/devices/me/attributes/request`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attribute-request-2.png,
+ title: Configure the device name and attribute settings. For device name expression, select source type as `Message` and enter `${serialNumber}` as the value. For attribute name expression, select source type as `Message` and enter `${versionAttribute}, ${pduAttribute}` as the value.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attribute-request-3.png,
+ title: Configure the response topic as `devices/${deviceName}/attrs` and the response value expression as `${attributeKey}: ${attributeValue}`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attribute-request-4.png,
+ title: Remember to save your changes by clicking the designated button.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameAttributeJson %}
+
+Let's demonstrate how to use these attribute request configurations with two examples:
+
+### Example 1: Device name and attribute from message payload
+
+Suppose we have a device with an attribute `firmwareVersion` stored as a shared attribute in ThingsBoard and suppose we want to request this attribute
+for some purposes.
+
+Let's add this attribute to the device `SN-001` in ThingsBoard first:
+
+1. Go to "**Devices**" → select device `SN-001` - "**Attributes**" tab - select "**Shared attributes**".
+
+2. Then click on the "**+**" icon and add `firmwareVersion` attribute with type "**String**" and set it to `1.2.3` click the "**Add**" button.
+
+
+
+This message contains the device name in the JSON payload, which is extracted using the `${serialNumber}` JSON path, and the attribute name using the `${attributeNames}` JSON path. After processing this message, ThingsBoard will retrieve the "firmwareVersion" attribute for device "SN-001" and publish it to the response topic.
+
+The response will be published to the topic `devices/SN-001/attrs` with a payload like: Let's subscribe to the response topic to see the result:
+Open terminal and type the following command and press Enter:
+
+```bash
+mosquitto_sub -h 127.0.0.1 -p 1884 -t devices/SN-001/attrs
+```
+{: .copy-code}
+
+Open another terminal to simulate sending a message from the device to the MQTT broker with the device name and attribute name in the JSON payload:
+
+```bash
+mosquitto_pub -h 127.0.0.1 -p 1884 -t v1/devices/me/attributes/request -m '{"serialNumber": "SN-001", "versionAttribute": "firmwareVersion"}'
+```
+{: .copy-code}
+
+This message contains the device name in the JSON payload, which is extracted using the `${serialNumber}` JSON path,
+and the attribute name using the `${attributeNames}` JSON path. After processing this message, ThingsBoard will retrieve the `firmwareVersion` attribute for device `SN-001` and publish it to the response topic.)
+
+
+
+```bash
+firmwareVersion: "1.2.3"
+```
+
+
+
+
+
+If you are using advanced configuration mode, you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "json",
+ "deviceInfo": {
+ "deviceNameExpressionSource": "message",
+ "deviceNameExpression": "${serialNumber}",
+ "deviceProfileExpressionSource": "message",
+ "deviceProfileExpression": "${sensorType}"
+ },
+ "timeout": 60000,
+ "attributes": [
+
+ ],
+ "timeseries": [
+ {
+ "type": "string",
+ "key": "temperature",
+ "value": "${temp}"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {
+ "attributeRequests": [
+ {
+ "retain": false,
+ "topicFilter": "v1/devices/me/attributes/request",
+ "deviceInfo": {
+ "deviceNameExpressionSource": "message",
+ "deviceNameExpression": "${serialNumber}"
+ },
+ "attributeNameExpressionSource": "message",
+ "attributeNameExpression": "${attributeNames}",
+ "topicExpression": "v1/devices/${deviceName}/attributes/response",
+ "valueExpression": "{\"${attributeKey}\": \"${attributeValue}\"}"
+ }
+ ]
+ }
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/attribute-update.md b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/attribute-update.md
new file mode 100644
index 0000000000..8943c2a6a7
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/attribute-update.md
@@ -0,0 +1,135 @@
+For Attribute updates, the gateway needs to know which devices should receive updates for which attributes. You configure this using regular expressions for both device names and attribute names. When an attribute is updated in ThingsBoard, the gateway publishes the new value to a configured MQTT topic.
+
+Suppose you want ThingsBoard to automatically push firmware version updates to your devices. When you update the `firmwareVersion` shared attribute in ThingsBoard, the gateway should publish this update to a topic that your devices are subscribed to.
+
+{% capture difference %}
+**Please note:**
+**Attribute updates** allow ThingsBoard to push shared attribute changes to devices. This is useful for:
+- Remotely configuring devices
+- Pushing firmware/software version information
+- Sending operational parameters to devices
+- Implementing device configuration management
+
+The gateway acts as a bridge, detecting attribute changes in ThingsBoard and publishing them to MQTT topics that devices can subscribe to.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+Let's configure Attribute updates in the MQTT connector to allow ThingsBoard to push attribute changes to devices.
+
+Follow these steps:
+
+{% assign AttributesUpdate = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" - "**Gateways**" in the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-gateway.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/mqtt-gateway-configuring-11-ce.png,
+ title: Select the MQTT connector, click on the "**Basic**". Click the "**Add mapping**" under "**Requests mapping**" section to add new attribute update mapping.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attribute-updates-1.png,
+ title: Select "**Attribute update**" in the **Request type** field, enter the "**Device name filter**" as `.*` to match all devices, or use a specific pattern to match only certain devices).
+ ===
+ image: /images/gateway/mqtt-connector/examples/attribute-updates-2.png,
+ title: Configure the **Attribute filter** as `firmwareVersion` to only update this specific attribute. Set the **Response topic expression** to `sensor/${deviceName}/${attributeKey}` and the **Response value expression** to `{"${attributeKey}":"${attributeValue}"}`. You can also set the **Retain** option to determine whether the attribute update message should be retained by the MQTT broker.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attribute-updates-3.png,
+ title: Remember to save your changes by clicking the designated button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/result-device-overview-attribute-updates-1.png,
+ title: Go to "**Devices**" - select device `SN-001` - "**Attributes**" tab - select "**Shared attributes**"
+ ===
+ image: /images/gateway/mqtt-connector/examples/result-device-overview-attribute-updates-2.png,
+ title: Add the `firmwareVersion` attribute with type "**String**" and set its value to "1.2.3".
+ ===
+ image: /images/gateway/mqtt-connector/examples/result-device-overview-attribute-updates-3.png,
+ title: Find the `firmwareVersion` attribute and click the pencil icon to edit it.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=AttributesUpdate %}
+
+Let's demonstrate how to use this attribute update configuration:
+
+### Example: Updating a device attribute in ThingsBoard
+
+1. First, let's subscribe to the topic where attribute updates will be published:
+
+```bash
+mosquitto_sub -h 127.0.0.1 -p 1884 -t sensor/SN-001/firmwareVersion
+```
+{: .copy-code}
+
+2. After updating the attribute in ThingsBoard, the gateway will detect the change and publish a message to the configured topic:
+
+```json
+{"firmwareVersion":"1.2.4"}
+```
+
+
+
+This message will be received by any device subscribed to the topic `sensor/SN-001/firmwareVersion`.
+
+
+
+If you are using advanced configuration mode, you can use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "json",
+ "deviceInfo": {
+ "deviceNameExpressionSource": "message",
+ "deviceNameExpression": "${serialNumber}",
+ "deviceProfileExpressionSource": "message",
+ "deviceProfileExpression": "${sensorType}"
+ },
+ "timeout": 60000,
+ "attributes": [
+
+ ],
+ "timeseries": [
+ {
+ "type": "string",
+ "key": "temperature",
+ "value": "${temp}"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {
+ "attributeUpdates": [
+ {
+ "retain": true,
+ "deviceNameFilter": ".*",
+ "attributeFilter": "firmwareVersion",
+ "topicExpression": "sensor/${deviceName}/${attributeKey}",
+ "valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}"
+ }
+ ]
+ }
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/configurable-rpc.md b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/configurable-rpc.md
new file mode 100644
index 0000000000..ce0cc6d738
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/configurable-rpc.md
@@ -0,0 +1,162 @@
+RPC to Device allows sending RPC commands to the device that is connected to ThingsBoard directly or via Gateway.
+
+Suppose we have a device `SN-001` that tracks the light level of the room and is connected to ThingsBoard via an MQTT Gateway.
+We want to send an RPC command to know the current state of the light level with two options: in the first case we want to get a response back, and in the second case we don't need a response.
+
+As an example, we will use ThingsBoard MQTT Demo Broker, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 1884:1884 thingsboard/tb-gw-mqtt-broker:latest
+```
+{:.copy-code}
+
+The demo broker runs at `0.0.0.0:1884` and simulates a device for our RPC examples. For configurable RPC, the device listens on topic `sensor/${deviceName}/request/${methodName}/${requestId}` for incoming commands and responds on topic `sensor/${deviceName}/response/${methodName}/${requestId}` when a response is expected.
+
+{% capture difference %}
+**Please note:**
+The RPC Debug Terminal is used only for example purposes, so you can use any other widget that supports RPC calls.
+The custom MQTT publisher is used only to simulate the device behavior, but it is not applicable for real-production
+use cases.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+Let's configure RPC commands in the MQTT connector to allow ThingsBoard to send commands to devices.
+
+Follow these steps:
+
+{% assign CustomRPC = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" - "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-gateway.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/mqtt-gateway-configuring-11-ce.png,
+ title: Select the MQTT connector, click on the "**Basic**". Click the "**Add mapping**" under "**Requests mapping**" section to add new RPC mapping.
+ ===
+ image: /images/gateway/mqtt-connector/examples/server-side-rpc-commands-1.png,
+ title: Select "**RPC command**" in the **Request type** field. For two-way RPC (with response).
+ ===
+ image: /images/gateway/mqtt-connector/examples/server-side-rpc-commands-2.png,
+ title: Configure the **Device name filter** as `.*` to apply to all devices, set the **Method filter** to `echo`, the **Request topic expression** to `sensor/${deviceName}/request/${methodName}/${requestId}`, the **Value expression** to `${params}`, the **Response topic expression** to `sensor/${deviceName}/response/${methodName}/${requestId}`, and set an appropriate **Response timeout** (e.g., 10000 ms).
+ ===
+ image: /images/gateway/mqtt-connector/examples/server-side-rpc-commands-3.png,
+ title: Remember to save your changes by clicking the designated button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/server-side-rpc-commands-4.png,
+ title: For one-way RPC (without response), click on the **Without response** tab. Configure the **Device name filter** as `.*` to apply to all devices, set the **Method filter** to `no-reply`, the **Request topic expression** to `sensor/${deviceName}/request/${methodName}/${requestId}`, and the **Value expression** to `${params}`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/server-side-rpc-commands-5.png,
+ title: Remember to save your changes by clicking the designated button.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=CustomRPC %}
+
+Let's demonstrate how to use this RPC configuration:
+
+### Example 1: Two Way RPC (with response)
+
+In the RPC Debug Terminal widget, run the following command to send a two-way RPC request:
+
+```bash
+echo {"deviceName":"SN-001", "methodName":"echo"}
+```
+{: .copy-code}
+
+The gateway will:
+1. Receive this RPC request
+2. Match it to the "echo" method configuration
+3. Send a message to the topic `sensor/SN-001/request/echo/12345` (where 12345 is a unique request ID)
+4. Subscribe to the topic `sensor/SN-001/response/echo/12345` to wait for a response
+5. Return the response to ThingsBoard when received
+
+
+
+### Example 2: One Way RPC (without response)
+
+In the RPC Debug Terminal widget, run the following command to send a one-way RPC request:
+
+```bash
+no-reply {"deviceName":"SN-001", "methodName":"no-reply"}
+```
+{: .copy-code}
+
+The gateway will:
+1. Receive this RPC request
+2. Match it to the "no-reply" method configuration
+3. Send a message to the topic `sensor/SN-001/request/no-reply/12345` (where 12345 is a unique request ID)
+4. Not wait for any response
+
+
+
+If you are using advanced configuration mode, you can use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "json",
+ "deviceInfo": {
+ "deviceNameExpressionSource": "message",
+ "deviceNameExpression": "${serialNumber}",
+ "deviceProfileExpressionSource": "message",
+ "deviceProfileExpression": "${sensorType}"
+ },
+ "timeout": 60000,
+ "attributes": [
+
+ ],
+ "timeseries": [
+ {
+ "type": "string",
+ "key": "temperature",
+ "value": "${temp}"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {
+ "serverSideRpc": [
+ {
+ "type": "twoWay",
+ "deviceNameFilter": ".*",
+ "methodFilter": "echo",
+ "requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
+ "responseTopicExpression": "sensor/${deviceName}/response/${methodName}/${requestId}",
+ "responseTopicQoS": 1,
+ "responseTimeout": 10000,
+ "valueExpression": "${params}"
+ },
+ {
+ "type": "oneWay",
+ "deviceNameFilter": ".*",
+ "methodFilter": "no-reply",
+ "requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
+ "valueExpression": "${params}"
+ }
+ ]
+ }
+}
+```
+{:.copy-code.expandable-15}
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/connect-request.md b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/connect-request.md
new file mode 100644
index 0000000000..6b4755e27b
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/connect-request.md
@@ -0,0 +1,122 @@
+For a Connect request, the gateway must know which device name to target. You can extract it either from the `Message` payload using [json-path](/docs/iot-gateway/config/mqtt/#json-path)
+or from the topic using a [regex](/docs/iot-gateway/config/mqtt/#regular-expressions). Choose [json-path](/docs/iot-gateway/config/mqtt/#json-path) when the device name is inside the JSON message; choose [regex](/docs/iot-gateway/config/mqtt/#regular-expressions) when it's encoded in the topic.
+
+Device `SN-001` hasn't sent telemetry for 10 minutes and is marked inactive, but you still need to send an RPC (and you're not planning to resume telemetry).
+Let's configure a Connect request in the MQTT connector to (re)announce the device so RPC can be delivered. We'll demonstrate two ways to extract the device name:
+
+- From message (`JSON` payload).
+- From topic (e.g., `sensor/SN-001/connect`).
+
+Follow these steps:
+
+{% assign deviceNameAndProfileTopicAndConstantJson = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" - "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/connect-request-gateway.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/mqtt-gateway-configuring-11-ce.png,
+ title: Select the MQTT connector, click on the "**Basic**". Click the "**Add mapping**" under "**Requests mapping**" section to add new connect request mapping.
+ ===
+ image: /images/gateway/mqtt-connector/examples/connect-request-1.png,
+ title: Select `Connect request` in the **Request type** field then fill the "**Topic filter**" with `sensor/connect`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/connect-request-2.png,
+ title: Select **Name** - source `Message` and **Profile name** - source `Constant`. In Value, enter `${serialNumber}` for the device name and `Thermometer` for the device profile.
+ ===
+ image: /images/gateway/mqtt-connector/examples/connect-request-3.png,
+ title: Remember to save your changes by clicking the designated button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/connect-request-4.png,
+ title: Select `Connect request` in the **Request type** field then fill the "**Topic filter**" with `sensor/+/connect`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/connect-request-5.png,
+ title: Select **Name** - source `Topic` and **Profile name** - source `Constant`. In Value, enter `(?<=sensor/)(.*?)(?=/connect)` for the device name and `Thermometer` for the device profile.
+ ===
+ image: /images/gateway/mqtt-connector/examples/connect-request-6.png,
+ title: Remember to save your changes by clicking the designated button.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameAndProfileTopicAndConstantJson %}
+
+After 10 minutes without sending telemetry, device `SN-001` is marked as inactive in ThingsBoard, as shown below:
+
+
+
+To reactivate the device so it can receive RPC commands, we need to send a Connect request. Let's demonstrate this with two examples:
+
+### Example 1: Device name from message payload
+
+Use a terminal to simulate sending a message from the device to the MQTT broker with the device name in the JSON payload:
+
+```bash
+mosquitto_pub -h 127.0.0.1 -p 1884 -t "sensor/connect" -m '{"serialNumber": "SN-001"}'
+```
+{: .copy-code}
+
+After sending this message, ThingsBoard updates both the lastActivityTime and lastConnectTime of the `SN-001` device, and its status changes to `Active`:
+
+
+
+
+
+
+### Example 2: Device name from topic
+
+The same reactivation can be achieved using the second mapping configuration, where the device name is extracted from the topic instead of the message payload:
+
+```bash
+mosquitto_pub -h 127.0.0.1 -p 1884 -t "sensor/SN-001/connect" -m ''
+```
+{: .copy-code}
+
+
+If you are using advanced configuration mode, you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [],
+ "requestsMapping": {
+ "connectRequests": [
+ {
+ "topicFilter": "sensor/connect",
+ "deviceInfo": {
+ "deviceNameExpression": "${serialNumber}",
+ "deviceNameExpressionSource": "message",
+ "deviceProfileExpressionSource": "constant",
+ "deviceProfileExpression": "Thermometer"
+ }
+ },
+ {
+ "topicFilter": "sensor/+/connect",
+ "deviceInfo": {
+ "deviceNameExpression": "(?<=sensor/)(.*?)(?=/connect)",
+ "deviceNameExpressionSource": "topic",
+ "deviceProfileExpressionSource": "constant",
+ "deviceProfileExpression": "Thermometer"
+ }
+ }
+ ]
+ }
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/disconnect-request.md b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/disconnect-request.md
new file mode 100644
index 0000000000..5486ba6030
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/disconnect-request.md
@@ -0,0 +1,127 @@
+For a Disconnect request, the gateway must know which device name to target. You can extract it either from the `Message` payload using [json-path](/docs/iot-gateway/config/mqtt/#json-path)
+or from the topic using a [regex](/docs/iot-gateway/config/mqtt/#regular-expressions). Choose [json-path](/docs/iot-gateway/config/mqtt/#json-path) when the device name is inside the JSON message; choose [regex](/docs/iot-gateway/config/mqtt/#regular-expressions) when it's encoded in the topic.
+
+Suppose you want to disconnect device `SN-001` from the platform immediately, without waiting for the 10-minute inactivity timeout-useful for dashboards, alarms,
+and rule chains that react to status changes.
+
+{% capture difference %}
+**Please note:**
+A **Disconnect request** tells the platform the device is offline **immediately** and stops routing **RPCs** and **attribute updates** to it.
+It does not block MQTT traffic: if the device (or gateway) continues publishing,
+new messages will arrive and the device may be marked active again based on the inactivity timeout which is 10 minutes.
+The UI “Active” flag follows last-activity timing; it may remain active until the timeout elapses unless no further messages arrive.
+.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+Let's configure a Disconnect request in the MQTT connector to notify the platform when a device disconnects.
+We'll demonstrate two ways to extract the device name:
+
+- From message (`JSON` payload).
+- From topic (e.g., `sensor/SN-001/disconnect`).
+
+Follow these steps:
+
+{% assign deviceNameDisconnectJson = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" - "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-gateway.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/mqtt-gateway-configuring-11-ce.png,
+ title: Select the MQTT connector, click on the "**Basic**". Click the "**Add mapping**" under "**Requests mapping**" section to add new disconnect request mapping.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-1.png,
+ title: Select "**Disconnect request**" in the **Request type** field, enter the "**Topic filter**" as `sensor/disconnect`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-2.png,
+ title: Select source type for **Name** field as `Message`. In Value, enter `${serialNumber}` for the device name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-3.png,
+ title: Remember to save your changes by clicking the designated button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-4.png,
+ title: Select "**Disconnect request**" in the **Request type** field then fill the "**Topic filter**" with `sensor/+/disconnect`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-5.png,
+ title: Select source type for **Name** field as `Topic`. In Value, enter `(?<=sensor/)(.*?)(?=/disconnect)` for the device name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/disconnect-request-6.png,
+ title: Remember to save your changes by clicking the designated button.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameDisconnectJson %}
+
+Let's demonstrate how to use these disconnect request configurations with two examples:
+
+
+
+### Example 1: Device name from message payload
+
+When the device name is included in the message payload, you can send a disconnect request as follows:
+
+```bash
+mosquitto_pub -h 127.0.0.1 -p 1884 -t "sensor/disconnect" -m '{"serialNumber": "SN-001"}'
+```
+{: .copy-code}
+
+This message contains the device name in the JSON payload, which is extracted using the `${serialNumber}` JSON path. After processing this message, ThingsBoard will mark the device `SN-001` as disconnected.
+
+
+
+### Example 2: Device name from topic
+
+When the device name is encoded in the topic path, you can send a disconnect request as follows:
+
+```bash
+mosquitto_pub -h 127.0.0.1 -p 1884 -t "sensor/SN-001/disconnect" -m ''
+```
+{: .copy-code}
+
+In this case, the device name is extracted from the topic using the regular expression `(?<=sensor/)(.*?)(?=/disconnect)`. After processing this message, ThingsBoard will mark the device `SN-001` as disconnected.
+
+If you are using advanced configuration mode, you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [],
+ "requestsMapping": {
+ "disconnectRequests": [
+ {
+ "topicFilter": "sensor/disconnect",
+ "deviceInfo": {
+ "deviceNameExpression": "${serialNumber}",
+ "deviceNameExpressionSource": "message"
+ }
+ },
+ {
+ "topicFilter": "sensor/+/disconnect",
+ "deviceInfo": {
+ "deviceNameExpression": "(?<=sensor/)(.*?)(?=/disconnect)",
+ "deviceNameExpressionSource": "topic"
+ }
+ }
+ ]
+ }
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/reserved-rpc.md b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/reserved-rpc.md
new file mode 100644
index 0000000000..6ec03bd014
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/request-mapping/reserved-rpc.md
@@ -0,0 +1,142 @@
+## Reserved RPC Methods
+
+`GET` and `SET` RPC methods are out of the box, so you don’t need to configure them manually.
+
+Suppose we have a device `SN-001` that tracks the light level of the room and is connected to ThingsBoard via an MQTT Gateway.
+We want to send an RPC command to know the current state of the light level with two options: in the first case we want to get a response back, and in the second case we don't need a response.
+Additionally, we will update the room light level by sending a command without expecting a response.
+
+As an example, we will use ThingsBoard MQTT Demo Broker, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 1884:1884 thingsboard/tb-gw-mqtt-broker:latest
+```
+{:.copy-code}
+
+The broker available at `0.0.0.0:1884` and simulates a device that listens to the topic `data/get_light_level` for getting the current light level and responds on the topic `data/response`.
+It also listens to the topic `data/set_light_level` to update the light level value.
+
+{% capture difference %}
+**Please note:**
+The RPC Debug Terminal is used only for example purposes, so you can use any other widget that supports RPC calls.
+The custom MQTT publisher is used only to simulate the device behavior, but it is not applicable for real-production
+use cases.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+### Example 1: Get current light level (Two Way RPC with response)
+
+In the RPC Debug Terminal widget, run the following command to send a two-way RPC request:
+
+```bash
+get requestTopicExpression=data/get_light_level;responseTopicExpression=data/response;value=${params};
+```
+{: .copy-code}
+
+The gateway will:
+1. Receive this RPC request
+2. Process the built-in "get" method
+3. Send a message to the topic `data/get_light_level` with the specified parameters
+4. Subscribe to the topic `data/response` to wait for a response
+5. Return the response to ThingsBoard when received
+
+
+
+### Example 2: Get current light level with no response (One Way RPC)
+
+In the RPC Debug Terminal widget, run the following command to send a one-way RPC request:
+
+```bash
+get requestTopicExpression=data/get_light_level;value=${params};
+```
+{: .copy-code}
+
+The gateway will:
+1. Receive this RPC request
+2. Process the built-in "get" method
+3. Send a message to the topic `data/get_light_level` with the specified parameters
+4. Not wait for any response since no response topic was specified
+
+
+
+### Example 3: SET new light level (One Way RPC)
+
+In the RPC Debug Terminal widget, run the following command to set a new light level value:
+
+```bash
+set requestTopicExpression=data/set_light_level;value=90;
+```
+{: .copy-code}
+
+The gateway will:
+1. Receive this RPC request
+2. Process the built-in "set" method
+3. Send a message to the topic `data/set_light_level` with the value "90"
+4. Not wait for any response since no response topic was specified
+
+
+
+### Example 4: Check updated light level (Two Way RPC with response)
+
+After setting the new light level, you can verify the updated value by running:
+
+```bash
+get requestTopicExpression=data/get_light_level;responseTopicExpression=data/response;value=${params};
+```
+{: .copy-code}
+
+The gateway will process this request as in Example 1, and you should see the updated light level value in the response.
+
+
+
+If you are using advanced configuration mode, you can use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "json",
+ "deviceInfo": {
+ "deviceNameExpressionSource": "message",
+ "deviceNameExpression": "${serialNumber}",
+ "deviceProfileExpressionSource": "message",
+ "deviceProfileExpression": "${sensorType}"
+ },
+ "timeout": 60000,
+ "attributes": [
+
+ ],
+ "timeseries": [
+ {
+ "type": "string",
+ "key": "temperature",
+ "value": "${temp}"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {
+ "serverSideRpc": []
+ }
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/attributes-time-series-bytes.md b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/attributes-time-series-bytes.md
new file mode 100644
index 0000000000..a2291ae164
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/attributes-time-series-bytes.md
@@ -0,0 +1,116 @@
+Attributes and time series data can be retrieved using [slices](/docs/iot-gateway/config/mqtt/#slices)
+in the MQTT Connector. This allows to extract the required field(s) from the `BYTES` payload received on the subscribed topic(s).
+
+As an example, we will use ThingsBoard MQTT Demo Broker, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 1884:1884 thingsboard/tb-gw-mqtt-broker:latest
+```
+{:.copy-code}
+
+The broker available at `0.0.0.0:1884` and publishes data to the topic `sensor/raw_data` with the following BYTES payload:
+
+`b"AM-120"` — Python bytes literal (ASCII)
+
+The first four bytes represent the device name, and the remaining bytes represent the temperature value.
+Configure the MQTT connector to store the entire raw payload in the `rawData` attribute, and to parse bytes 5–6 as the `temperature` and publish it as the temp timeseries.
+Then configure the device name and profile in the MQTT connector.
+
+Follow these steps:
+
+{% assign deviceNameAndProfileIdentifierPath = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" → "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-2.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-3.png,
+ title: Select the MQTT connector, click on the "**Data mapping**" tab. Select data mapping with device to which you want to add time series data (if you do not know how to add a new device, see the [Getting Started](/docs/iot-gateway/getting-started/?connectorsCreation=opcua){:target="_blank"} guide or [Data mapping](/docs/iot-gateway/config/opc-ua/#data-mapping) section of this guide with respective examples).
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-bytes-2.png,
+ title: In the opened data mapping windows, click on the "**pencil**" icon next to the "**Attributes**" section.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-bytes-3.png,
+ title: Click on the "**Add attribute**" button. Fill in the "**Key**" field with `rawData`, also select `Raw` in "**Type**" field, and fill in the "**Value**" field with `[:]`. Those are [slices](/docs/iot-gateway/config/mqtt/#slices).
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-bytes-4.png,
+ title: Remember to save your changes by clicking the designated button on the screenshot.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-bytes-5.png,
+ title: In the opened data mapping windows, click on the "**pencil**" icon next to the "**Time series**" section.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-bytes-6.png,
+ title: Click on the "**Add time series**" button. Fill in the "**Key**" field with `temp`, also select `Raw` in "**Type**" field, and fill in the "**Value**" field with `[4:]`. Those are [slices](/docs/iot-gateway/config/mqtt/#slices).
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-bytes-7.png,
+ title: Remember to save your changes by clicking the designated button on the screenshot.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameAndProfileIdentifierPath %}
+
+Now we can check if the attribute data is set correctly. Go to "**Entities**" > "**Devices**", select a created device and as you
+can see, the humidity data is available in the "**Attributes**" section:
+
+
+
+Now we can check if the temperature data is sending correctly. Go to "**Entities**" > "**Devices**", select a created device and as you
+can see, the humidity data is available in the "**Latest telemetry**" section:
+
+
+
+If you are using advanced configuration mode and want to set the `temperature` and `model` data using [json-path](/docs/iot-gateway/config/mqtt/#json-path), you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/raw_data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "bytes",
+ "deviceInfo": {
+ "deviceNameExpression": "[0:4]",
+ "deviceNameExpressionSource": "message",
+ "deviceProfileExpressionSource": "constant",
+ "deviceProfileExpression": "default"
+ },
+ "attributes": [
+ {
+ "key": "rawData",
+ "type": "raw",
+ "value": "[:]"
+ }
+ ],
+ "timeseries": [
+ {
+ "key": "temp",
+ "type": "raw",
+ "value": "[4:]"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {}
+}
+````
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/attributes-time-series-json-path.md b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/attributes-time-series-json-path.md
new file mode 100644
index 0000000000..4c45c4b0de
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/attributes-time-series-json-path.md
@@ -0,0 +1,120 @@
+Attributes and time series data can be retrieved using [json-path](/docs/iot-gateway/config/mqtt/#json-path)
+in the MQTT Connector. This allows to extract the required field(s) from the `JSON` payload received on the subscribed topic(s).”.
+
+As an example, we will use ThingsBoard MQTT Demo Broker, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 1884:1884 thingsboard/tb-gw-mqtt-broker:latest
+```
+{:.copy-code}
+
+The broker available at `0.0.0.0:1884` and publishes data to the topic `sensor/data` with the following JSON payload:
+
+```json
+{
+ "serialNumber": "SN-001",
+ "sensorType": "Thermometer",
+ "sensorModel": "T-100",
+ "temp": 22.82,
+ "hum": 59.3
+}
+```
+We’ll map `sensorModel` → `model` and `temp` → timeseries `temperature`. Next, configure the device name and profile in the MQTT connector.
+Follow these steps:
+
+{% assign deviceNameAndProfileTopicAndConstantJson = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" → "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-2.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-3.png,
+ title: Select the MQTT connector, click on the "**Data mapping**" tab. Select data mapping with device to which you want to add time series data (if you do not know how to add a new device, see the [Getting Started](/docs/iot-gateway/getting-started/?connectorsCreation=opcua){:target="_blank"} guide or [Data mapping](/docs/iot-gateway/config/opc-ua/#data-mapping) section of this guide with respective examples).
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-json-path-2.png,
+ title: In the opened data mapping windows, click on the "**pencil**" icon next to the "**Attributes**" section.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-json-path-3.png,
+ title: Click on the "**Add attribute**" button. Fill in the "**Key**" field with `model`, also select `String` in "**Type**" field, and fill in the "**Value**" field with `${sensorModel}`. This is a [json-path](/docs/iot-gateway/config/mqtt/#json-path).
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-json-path-4.png,
+ title: Remember to save your changes by clicking the designated button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-json-path-5.png,
+ title: In the opened data mapping windows, click on the "**pencil**" icon next to the "**Time series**" section.
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-json-path-6.png,
+ title: Click on the "**Add time series**" button. Fill in the "**Key**" field with `temperature`, also select `Double` in "**Type**" field, and fill in the "**Value**" field with [json-path](/docs/iot-gateway/config/mqtt/#json-path) - `${temp}`. This is a [json-path](/docs/iot-gateway/config/mqtt/#json-path).
+ ===
+ image: /images/gateway/mqtt-connector/examples/attributes-time-series-json-path-7.png,
+ title: Remember to save your changes by clicking the designated button.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameAndProfileTopicAndConstantJson %}
+
+Now we can check if the attribute data is set correctly. Go to "**Entities**" > "**Devices**", select a created device and as you
+can see, the humidity data is available in the "**Attributes**" section:
+
+
+
+Now we can check if the temperature data is sending correctly. Go to "**Entities**" > "**Devices**", select a created device and as you
+can see, the humidity data is available in the "**Latest telemetry**" section:
+
+
+
+If you are using advanced configuration mode and want to set the `temperature` and `model` data using [json-path](/docs/iot-gateway/config/mqtt/#json-path), you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "json",
+ "deviceInfo": {
+ "deviceNameExpression": "${serialNumber}",
+ "deviceNameExpressionSource": "message",
+ "deviceProfileExpressionSource": "message",
+ "deviceProfileExpression": "${sensorType}"
+ },
+ "attributes": [
+ {
+ "key": "model",
+ "type": "string",
+ "value": "${sensorModel}"
+ }
+ ],
+ "timeseries": [
+ {
+ "key": "temperature",
+ "type": "double",
+ "value": "${temp}"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {}
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-message-and-constant-bytes.md b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-message-and-constant-bytes.md
new file mode 100644
index 0000000000..a7a59218f1
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-message-and-constant-bytes.md
@@ -0,0 +1,102 @@
+The device name and profile can be extracted from the message source and bytes payload. In this example, we will use
+[slices](/docs/iot-gateway/config/mqtt/#slices) to specify the device name and constant for profile.
+
+As an example, we will use ThingsBoard MQTT Demo Broker, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 1884:1884 thingsboard/tb-gw-mqtt-broker:latest
+```
+{:.copy-code}
+
+The broker available at `0.0.0.0:1884` and publishes data to the topic `sensor/raw_data` with the following BYTES payload:
+
+`b"AM-120"` — Python bytes literal (ASCII)
+
+Suppose we want to create a device from this payload. The first four bytes represent the device name, and the remaining bytes represent the temperature value.
+
+Configure the MQTT connector to extract the device name from the raw bytes and use a constant value for the device profile (for example, `default`).
+
+Follow these steps:
+
+{% assign deviceNameAndProfileTopicAndConstantJson = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" → "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-2.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-3.png,
+ title: Select the created MQTT connector, select "**Basic**" click on the "**Data mapping**" Click on the "**+ Add mapping**" button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-and-constant-bytes-4.png,
+ title: In the opened window, fill in "**Topic filter**" field with `sensor/raw_data`, also fill "**QoS**" with one of these values(`0`,`1`,`2`) and for "**Payload type**" select `Bytes`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-and-constant-bytes-5.png,
+ title: Then under "**Device**" subsection choose "**Message**" for the "**Name**" field, enter `[0:4]`, those are the [slices](/docs/iot-gateway/config/mqtt/#slices) used to extract device name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-and-constant-bytes-6.png,
+ title: Then under "**Profile name**" subsection choose "**Constant**" for the "**Name**" field, enter `default`, this is **Constant** value that will be used to form device profile name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-and-constant-bytes-7.png,
+ title: Also, we need to add at least one attribute/time series because the connector will not add a device without any data to read as we remember. The first four bytes represent the device name, and the remaining bytes represent the temperature value. Click on the "**pencil**" icon next to the "**Time series**" section.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-and-constant-bytes-8.png,
+ title: In the opened window, click on the "**Add time series**" button and fill the fields as on the corresponding image. Do not forget to save changes.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameAndProfileTopicAndConstantJson %}
+
+Now we can check if the device name and profile are set correctly. Go to "**Entities**" > "**Devices**" and as you can see, the device
+name is set to `AM-1` and the profile is set to `default`.
+
+
+
+If you are using advanced configuration mode and want to set the device name and profile using topic and json path, you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/raw_data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "bytes",
+ "deviceInfo": {
+ "deviceNameExpression": "[0:4]",
+ "deviceNameExpressionSource": "message",
+ "deviceProfileExpressionSource": "constant",
+ "deviceProfileExpression": "default"
+ },
+ "attributes": [],
+ "timeseries": [
+ {
+ "key": "temp",
+ "type": "raw",
+ "value": "[4:]"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {}
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-message-json.md b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-message-json.md
new file mode 100644
index 0000000000..f0879ffb1d
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-message-json.md
@@ -0,0 +1,112 @@
+The device name and profile can be extracted from the incoming message. In this example, we will use
+[json path](/docs/iot-gateway/config/mqtt/#json-path) to specify the device name and profile.
+
+As an example, we will use ThingsBoard MQTT Demo Broker, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 1884:1884 thingsboard/tb-gw-mqtt-broker:latest
+```
+{:.copy-code}
+
+The broker available at `0.0.0.0:1884` and publishes data to the topic `sensor/data` with the following JSON payload:
+
+```json
+{
+ "serialNumber": "SN-001",
+ "sensorType": "Thermometer",
+ "sensorModel": "T-100",
+ "temp": 22.82,
+ "hum": 59.3
+}
+```
+We also want to extract the device name from the `serialNumber` field and the device profile from the `sensorType` field.
+Let's configure the device name and profile in the MQTT connector. For this purpose, follow these steps:
+
+{% assign deviceNameAndProfileTopicAndConstantJson = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" → "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-2.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-3.png,
+ title: Select the created MQTT connector, select "**Basic**" click on the "**Data mapping**" Click on the "**+ Add mapping**" button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-4.png,
+ title: In the opened window, fill in "**Topic filter**" field with `sensor/data`, also fill "**QoS**" with one of these values(`0`,`1`,`2`) and for "**Payload type**" select `JSON`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-5.png,
+ title: Then under "**Device**" subsection choose "**Message**" for the "**Name**" field, enter `${serialNumber}`, this is the [json path](/docs/iot-gateway/config/mqtt/#json-path) to the field that contains the device name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-6.png,
+ title: Then under "**Profile name**" subsection choose "**Message**" for the "**Name**" field, enter `${sensorType}`, this is the [json path](/docs/iot-gateway/config/mqtt/#json-path) to the field that contains the device name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-7.png,
+ title: Also, we need to add at least one attribute/time series because the connector will not add a device without any data to read. Click on the "**pencil**" icon next to the "**Time series**" section.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-8.png,
+ title: In the opened window, click on the "**Add time series**" button and fill the fields as on the corresponding image. Do not forget to save changes.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameAndProfileTopicAndConstantJson %}
+
+Now we can check if the device name and profile are set correctly. Go to "**Entities**" > "**Devices**" and as you can see, the device
+name is set to `SN-001` and the profile is set to `Thermometer`.
+
+
+
+If you are using advanced configuration mode and want to set the device name and profile using topic and json path, you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "json",
+ "deviceInfo": {
+ "deviceNameExpression": "${serialNumber}",
+ "deviceNameExpressionSource": "message",
+ "deviceProfileExpressionSource": "message",
+ "deviceProfileExpression": "${sensorType}"
+ },
+ "attributes": [
+ {
+ "key": "model",
+ "type": "string",
+ "value": "${sensorModel}"
+ }
+ ],
+ "timeseries": [
+ {
+ "key": "temperature",
+ "type": "double",
+ "value": "${temp}"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {}
+}
+```
+{:.copy-code.expandable-15}
diff --git a/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-topic-and-constant-json.md b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-topic-and-constant-json.md
new file mode 100644
index 0000000000..6f1032a78f
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/examples/time-series-and-attributes/device-name-and-profile-topic-and-constant-json.md
@@ -0,0 +1,107 @@
+The device name and profile can be extracted from the topic. In this example, we will use
+[regex](/docs/iot-gateway/config/mqtt/#regular-expressions) to specify the device name and constant for profile.
+
+As an example, we will use ThingsBoard MQTT Demo Broker, which can be run using Docker and the following command:
+
+```bash
+docker run -it -p 1884:1884 thingsboard/tb-gw-mqtt-broker:latest
+```
+{:.copy-code}
+
+The broker available at `0.0.0.0:1884` and publishes data to the topic `sensor/Thermo-A/data` where `Thermo-A` is the device name: with the following JSON payload:
+
+```json
+{
+ "sensorModel": "T-100",
+ "temp": 23.82,
+ "hum": 60.3
+}
+```
+To match this topic, either enter `sensor/Thermo-A/data` in **Topic filter** field or use [wildcards](/docs/iot-gateway/config/mqtt/#wildcard-usage)
+to subscribe to both `sensor/Thermo-A/data` and let's say `sensor/Thermo-B/data`.
+
+Let’s configure the MQTT connector to take the device name from the topic and use a constant for the device profile (e.g., `Thermometer`).
+Follow these steps:
+
+{% assign deviceNameAndProfileTopicAndConstantJson = '
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-1.png,
+ title: Go to "**Entities**" → "**Gateways**" on the left sidebar and select your gateway.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-2.png,
+ title: Click on the "**Connectors configuration**" button on the right side menu.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-3.png,
+ title: Select the created MQTT connector, select "**Basic**" click on the "**Data mapping**" Click on the "**+ Add mapping**" button.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-topic-constant-json-4.png,
+ title: In the opened window, fill in "**Topic filter**" field with `sensor/+/data`, also fill "**QoS**" with one of these values(`0`,`1`,`2`) and for "**Payload type**" select `JSON`.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-topic-constant-json-5.png,
+ title: Then under "**Device**" subsection choose "**Topic**" for the "**Name**" field, enter `(?<=sensor/)(.*?)(?=/data)`, this is the [regex](/docs/iot-gateway/config/mqtt/#regular-expressions) used to extract device name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-topic-constant-json-6.png,
+ title: Then under "**Profile name**" subsection choose "**Constant**" for the "**Name**" field, enter `Thermometer`, this is **Constant** value that will be used to form device profile name.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-topic-constant-json-7.png,
+ title: Also, we need to add at least one attribute/time series because the connector will not add a device without any data to read. Click on the "**pencil**" icon next to the "**Time series**" section.
+ ===
+ image: /images/gateway/mqtt-connector/examples/device-name-and-profile-message-json-8.png,
+ title: In the opened window, click on the "**Add time series**" button and fill the fields as on the corresponding image. Do not forget to save changes.
+'
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=deviceNameAndProfileTopicAndConstantJson %}
+
+Now we can check if the device name and profile are set correctly. Go to "**Entities**" > "**Devices**" and as you can see, the device
+name is set to `Thermo-A` and the profile is set to `Thermometer`.
+
+
+
+If you are using advanced configuration mode and want to set the device name and profile using topic and json path, you can
+use the following configuration:
+
+```json
+{
+ "broker": {
+ "host": "127.0.0.1",
+ "port": 1884,
+ "clientId": "ThingsBoard_gateway",
+ "version": 5,
+ "maxMessageNumberPerWorker": 10,
+ "maxNumberOfWorkers": 100,
+ "keepAlive": 60,
+ "cleanSession": true,
+ "cleanStart": true,
+ "sessionExpiryInterval": 0,
+ "security": {
+ "type": "anonymous"
+ }
+ },
+ "mapping": [
+ {
+ "topicFilter": "sensor/+/data",
+ "subscriptionQos": 1,
+ "converter": {
+ "type": "json",
+ "deviceInfo": {
+ "deviceNameExpression": "(?<=sensor/)(.*?)(?=/data)",
+ "deviceNameExpressionSource": "topic",
+ "deviceProfileExpressionSource": "constant",
+ "deviceProfileExpression": "Thermometer"
+ },
+ "attributes": [],
+ "timeseries": [
+ {
+ "key": "temperature",
+ "type": "double",
+ "value": "${temp}"
+ }
+ ]
+ }
+ }
+ ],
+ "requestsMapping": {}
+}
+```
+{:.copy-code.expandable-15}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/mqtt-attr-and-time-series-basic-section.md b/_includes/templates/iot-gateway/mqtt-connector/mqtt-attr-and-time-series-basic-section.md
new file mode 100644
index 0000000000..05e0225033
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/mqtt-attr-and-time-series-basic-section.md
@@ -0,0 +1,40 @@
+To add new time series or attribute key, follow these steps:
+
+{% assign attrAndTimeseries = '
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-3-ce.png,
+ title: Click the “**pencil**” icon in the “**Attributes**” section to add new attribute key;
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-4-ce.png,
+ title: Click on "**Add attribute**" in the opened window;
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-5-ce.png,
+ title: Enter the "**Key**" field, select the "**Type**" (It could be one of the following `string`, `boolean`, `integer`, `double` or `Raw` if the **Payload type** `Bytes`.), enter "**Value**" and click "**Apply**" button;
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-6-ce.png,
+ title: Now click on the “**pencil**” icon in the “**Time series**” section to add new time series key;
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-7-ce.png,
+ title: Click on "**Add time series**" in the opened window;
+ ===
+ image: /images/gateway/mqtt-connector/mqtt-gateway-configuring-8-ce.png,
+ title: Enter the "**Key**" field, select the "**Type**" (It could be one of the following `string`, `boolean`, `integer`, `double` or `Raw` if the **Payload type** `Bytes`.), enter "**Value**" and click "**Apply**" button.
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=attrAndTimeseries %}
+
+You can enable a specific report strategy for each time series or attribute. This strategy defines how often
+data is sent to the ThingsBoard server. The following strategies are available:
+
+- **On report period** - sends data to ThingsBoard after the report period;
+- **On value change** - sends data to ThingsBoard when the value changes;
+- **On value change or report period** - sends data to ThingsBoard when the value changes or after the report period;
+- **On received** - sends data to ThingsBoard after receiving data from the device (default strategy).
+
+{% capture difference %}
+Additional information about the report strategy can be found [here](/docs/iot-gateway/features-overview/report-strategy){:target="_blank"}.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+
diff --git a/_includes/templates/iot-gateway/mqtt-connector/mqtt-basic-section.md b/_includes/templates/iot-gateway/mqtt-connector/mqtt-basic-section.md
new file mode 100644
index 0000000000..dbfda5a1cd
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/mqtt-basic-section.md
@@ -0,0 +1,40 @@
+This configuration section contains settings of the MQTT broker connection, such as:
+- **Host** - MQTT broker hostname or ip address;
+- **Port** - listening port on the MQTT broker that will be used for establishing connection;
+- **MQTT version** - MQTT protocol version (there are three versions currently supported by gateway - **3.1**, **3.11**, **5**);
+- **Client ID** ** - Unique identifier for each client’s session on the broker;
+- **Security** - configuration for client authorization at MQTT Broker (anonymous, basic, or certificates).
+
+{% capture difference %}
+**Please note:**
+\** -- The broker (or broker cluster) does not allow two simultaneous sessions with the same **Client ID**. If a second connection uses that ID,
+the broker closes the existing session and accepts the new one (session takeover). The **Client ID** can be any valid UTF-8 string;
+if you don’t have a descriptive one, you can generate it in the MQTT connector configuration UI—see the last screenshots under this subsection.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+{% capture difference %}
+All configuration parameters list, and their detailed description can be found in the
+[Advanced configuration](/docs/iot-gateway/config/mqtt/#advanced-configuration) section.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+
+
+If you want the UI to generate a **Client ID**, leave the **Client ID** field blank and click *Generate Client ID* (see the screenshot below).
+The gateway will create a unique identifier.
+
+
+
+UI form with generated **Client ID** identifier e.g., *tb_gw_rfpev* — this is just an example; your value will be different.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/_includes/templates/iot-gateway/mqtt-connector/requests-mapping-section-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/requests-mapping-section-advanced.md
deleted file mode 100644
index 682e60dd8d..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/requests-mapping-section-advanced.md
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/requests-mapping-section-basic.md b/_includes/templates/iot-gateway/mqtt-connector/requests-mapping-section-basic.md
deleted file mode 100644
index c8b4a37a18..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/requests-mapping-section-basic.md
+++ /dev/null
@@ -1,7 +0,0 @@
-For adding new requests mapping, click "plus" icon:
-
-
-
-Modal window will open. Select request type, set a topic filter, fill in the entities fields of the "Device" section. Then, click "Add".
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-basic-anonymous-subsection.md b/_includes/templates/iot-gateway/mqtt-connector/security-basic-anonymous-subsection.md
deleted file mode 100644
index 899bed9533..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/security-basic-anonymous-subsection.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Anonymous auth is the most simple option. It is useful for testing on public MQTT brokers, like test.mosquitto.org.
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-basic-basic-subsection.md b/_includes/templates/iot-gateway/mqtt-connector/security-basic-basic-subsection.md
deleted file mode 100644
index 49fd171370..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/security-basic-basic-subsection.md
+++ /dev/null
@@ -1,3 +0,0 @@
-One type of security configuration is basic. For authorization, a combination of username and password provided in this section, in config will be used.
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-config-anonymous.md b/_includes/templates/iot-gateway/mqtt-connector/security-config-anonymous.md
deleted file mode 100644
index 09c384fb6a..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/security-config-anonymous.md
+++ /dev/null
@@ -1,17 +0,0 @@
-Anonymous auth is the most simple option. It is useful for testing on public MQTT brokers, like test.mosquitto.org.
-
-
-|**Parameter**|**Default value**|**Description**|
-|:-|:-|-
-| type | **anonymous** | Type of authorization. |
-|---
-
-Security subsection in configuration file will look like this:
-
-```json
- "security": {
- "type": "anonymous"
- }
-```
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-config-basic.md b/_includes/templates/iot-gateway/mqtt-connector/security-config-basic.md
deleted file mode 100644
index ce58cd214a..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/security-config-basic.md
+++ /dev/null
@@ -1,22 +0,0 @@
-One type of security configuration is basic.
-For authorization, a combination of username and password provided in this section, in config will be used.
-
-
-| **Parameter** | **Default value** | **Description** |
-|:--------------|:------------------|-----------------------------|
-| type | **basic** | Type of authorization. |
-| username | **username** | Username for authorization. |
-| password | **password** | Password for authorization. |
-| ---
-
-Security subsection in configuration file will look like this:
-
-```json
- "security": {
- "type": "basic",
- "username": "username",
- "password": "password"
- }
-```
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-config-certificates.md b/_includes/templates/iot-gateway/mqtt-connector/security-config-certificates.md
deleted file mode 100644
index c212ee11c0..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/security-config-certificates.md
+++ /dev/null
@@ -1,22 +0,0 @@
-The table below describes the parameters required to configure authorization on MQTT broker.
-
-| **Parameter** | **Default value** | **Description** |
-|:------------------|:---------------------------------------------|----------------------------
-| type | **certificates** | Type of authorization. |
-| pathToCACert | **/etc/thingsboard-gateway/ca.pem** | Path to CA file. |
-| pathToPrivateKey | **/etc/thingsboard-gateway/privateKey.pem** | Path to private key file. |
-| pathToClientCert | **/etc/thingsboard-gateway/certificate.pem** | Path to certificate file. |
-| ---
-
-Security subsection in configuration file will look like this:
-
-```json
-"security":{
- "type": "certificates",
- "pathToCACert": "/etc/thingsboard-gateway/ca.pem",
- "pathToPrivateKey": "/etc/thingsboard-gateway/privateKey.pem",
- "pathToClientCert": "/etc/thingsboard-gateway/certificate.pem"
-}
-```
-
-
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/security-subsection-advanced.md
deleted file mode 100644
index 70a6dc9959..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/security-subsection-advanced.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Now select the security type:
-
-{% capture mqttsecurityadvancedsubsection %}
-AnonymousNo security%,%anonymous%,%templates/iot-gateway/mqtt-connector/security-config-anonymous.md%br%
-BasicRecommended%,%basic%,%templates/iot-gateway/mqtt-connector/security-config-basic.md%br%
-CertificatesFor advanced security%,%certificates%,%templates/iot-gateway/mqtt-connector/security-config-certificates.md{% endcapture %}
-
-{% include content-toggle.liquid content-toggle-id="mqttsecurityadvancedsubsection" toggle-spec=mqttsecurityadvancedsubsection %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-subsection-anonymous.md b/_includes/templates/iot-gateway/mqtt-connector/security-subsection-anonymous.md
new file mode 100644
index 0000000000..34b83c0d22
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/security-subsection-anonymous.md
@@ -0,0 +1,11 @@
+**Anonymous** is the simplest option: no credentials are required to publish/subscribe on the MQTT broker.
+It can be useful for testing (e.g., public test brokers),
+but not recommended for production because it allows unattended access..
+
+{% assign securityBasic = '
+ ===
+ image: /images/gateway/mqtt-connector/security-basic-anonymous-subsection-1-ce.png,
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=securityBasic %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/security-subsection-basic.md
index d050591ff2..7f3a236c1c 100644
--- a/_includes/templates/iot-gateway/mqtt-connector/security-subsection-basic.md
+++ b/_includes/templates/iot-gateway/mqtt-connector/security-subsection-basic.md
@@ -1,8 +1,11 @@
-Now select the security type:
+**Basic** authentication option uses a **username** and **password** configured on the MQTT broker.
+It’s a good default for most setups - just use strong, unique credentials. For stronger identity and mutual verification,
+consider certificate-based authentication.
-{% capture mqttsecuritybasicsubsection %}
-AnonymousNo security%,%anonymous%,%templates/iot-gateway/mqtt-connector/security-basic-anonymous-subsection.md%br%
-BasicRecommended%,%basic%,%templates/iot-gateway/mqtt-connector/security-basic-basic-subsection.md%br%
-CertificatesFor advanced security%,%certificates%,%templates/iot-gateway/mqtt-connector/security-basic-certificates-subsection.md{% endcapture %}
+{% assign securityBasic = '
+ ===
+ image: /images/gateway/mqtt-connector/security-basic-basic-subsection-1-ce.png,
+ '
+%}
-{% include content-toggle.liquid content-toggle-id="mqttsecuritybasicsubsection" toggle-spec=mqttsecuritybasicsubsection %}
\ No newline at end of file
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=securityBasic %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/security-subsection-certificates.md b/_includes/templates/iot-gateway/mqtt-connector/security-subsection-certificates.md
new file mode 100644
index 0000000000..38d2090fb2
--- /dev/null
+++ b/_includes/templates/iot-gateway/mqtt-connector/security-subsection-certificates.md
@@ -0,0 +1,12 @@
+**Certificate-based authentication** uses TLS so the gateway and broker verify each other.
+Set the **Path to CA certificate file** to your CA certificate (to trust the broker), **Path to client certificate file**
+to the gateway’s client certificate, and **Path to private key file** to its private key (so the broker can authenticate the gateway).
+Use the broker’s TLS port (typically 8883) for encrypted, production-grade security.
+
+{% assign securityBasic = '
+ ===
+ image: /images/gateway/mqtt-connector/security-basic-certificates-subsection-1-ce.png,
+ '
+%}
+
+{% include images-gallery.liquid showListImageTitles="true" imageCollection=securityBasic %}
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/server-side-rpc-commands-subsection-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/server-side-rpc-commands-subsection-advanced.md
deleted file mode 100644
index 4fd560dfcc..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/server-side-rpc-commands-subsection-advanced.md
+++ /dev/null
@@ -1,65 +0,0 @@
-
-This section in configuration file looks like:
-
-```json
-"serverSideRpc": [
- {
- "type": "twoWay",
- "deviceNameFilter": ".*",
- "methodFilter": "echo",
- "requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
- "responseTopicExpression": "sensor/${deviceName}/response/${methodName}/${requestId}",
- "responseTopicQoS": 1,
- "responseTimeout": 10000,
- "valueExpression": "${params}"
- },
- {
- "type": "oneWay",
- "deviceNameFilter": ".*",
- "methodFilter": "no-reply",
- "requestTopicExpression": "sensor/${deviceName}/request/${methodName}/${requestId}",
- "valueExpression": "${params}"
- }
-]
-```
-{: .copy-code}
-
-
-
-| **Parameter** | **Default value** | **Description** |
-|:------------------------|:-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------
-| deviceNameFilter | **.\*** | Regular expression device name filter, is used to determine, which function to execute. |
-| methodFilter | **echo** | Regular expression method name filter, is used to determine, which function to execute. |
-| requestTopicExpression | **sensor/${deviceName}/request/${methodName}/${requestId}** | JSON-path expression, is used for creating topic address to send RPC request. |
-| responseTopicExpression | **sensor/${deviceName}/response/${methodName}/${requestId}** | JSON-path expression, is used for creating topic address to subscribe for response message. |
-| responseTimeout | **10000** | Value in milliseconds. If there is no response within this period after sending the request, gateway will unsubscribe from the response topic. |
-| valueExpression | **${params}** | JSON-path expression, is used for creating data for sending to broker. |
-| ---
-
-{% capture methodFilterOptions %}
-There are 2 options for RPC request:
-1. **With a response** -- If the configuration includes a responseTopicExpression, the gateway will attempt to subscribe to it and wait for a response.
-2. **Without a response** -- If the configuration does not include a responseTopicExpression, the gateway will simply send the message without waiting for a response.
- {% endcapture %}
- {% include templates/info-banner.md content=methodFilterOptions %}
-
-You can use **deviceNameFilter** and **methodFilter** to apply different mapping rules for various devices/methods.
-Once Gateway receives RPC request from the server to the device, it will publish the corresponding message based on **requestTopicExpression** and **valueExpression**.
-In case you expect a reply to the request from the device, you should also specify **responseTopicExpression** and **responseTimeout**.
-The Gateway will subscribe to the "response" topic and wait for a device reply until "responseTimeout" is reached (in milliseconds).
-
-Here is an example of an RPC request (rpc-request.json) that needs to be sent from the server:
-
-```json
-{
- "method": "echo",
- "params": {
- "message": "Hello!"
- }
-}
-```
-
-Also, every telemetry and attribute parameter has built-in GET and SET RPC methods out of the box, so you don’t need to configure
-it manually. To use them, make sure you set all the required parameters (in the case of MQTT Connector, these are the following:
-**requestTopicExpression**, **responseTopicExpression**, **responseTimeout**, **valueExpression**).
-See [the guide](/docs/iot-gateway/guides/how-to-use-get-set-rpc-methods).
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/server-side-rpc-commands-subsection-basic.md b/_includes/templates/iot-gateway/mqtt-connector/server-side-rpc-commands-subsection-basic.md
deleted file mode 100644
index 1af9dd0d90..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/server-side-rpc-commands-subsection-basic.md
+++ /dev/null
@@ -1,45 +0,0 @@
-There are 2 options for RPC request:
-**With a response** -- If the configuration includes a responseTopicExpression, the gateway will attempt to subscribe to it and wait for a response.
-
-To adding new requests mapping, navigate to the "Requests mapping" tab and click the "plus" icon.
-In the open modal window, select the "RPC command" request type, and set a device name filter, method filter, request topic expression, value expression, response topic expression, response topic QoS and response timeout. Then, click "Add".
-
-
-
-**Without a response** -- If the configuration does not include a responseTopicExpression, the gateway will simply send the message without waiting for a response.
-
-To adding new requests mapping, navigate to the "Requests mapping" tab and click the "plus" icon.
-In the open modal window, select the "RPC command" request type, toggle "Without response" option, and set a device name filter, method filter, and value expression. Then, click "Add".
-
-
-
-| **Parameter** | **Default value** | **Description** |
-|:------------------------|:-------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------
-| deviceNameFilter | **.\*** | Regular expression device name filter, is used to determine, which function to execute. |
-| methodFilter | **echo** | Regular expression method name filter, is used to determine, which function to execute. |
-| requestTopicExpression | **sensor/${deviceName}/request/${methodName}/${requestId}** | JSON-path expression, is used for creating topic address to send RPC request. |
-| responseTopicExpression | **sensor/${deviceName}/response/${methodName}/${requestId}** | JSON-path expression, is used for creating topic address to subscribe for response message. |
-| responseTimeout | **10000** | Value in milliseconds. If there is no response within this period after sending the request, gateway will unsubscribe from the response topic. |
-| valueExpression | **${params}** | JSON-path expression, is used for creating data for sending to broker. |
-| ---
-
-You can use **device name filter** and **method filter** to apply different mapping rules for various devices/methods.
-Once Gateway receives RPC request from the server to the device, it will publish the corresponding message based on **request topic expression** and **value expression**.
-In case you expect a reply to the request from the device, you should also specify **response topic expression** and **response timeout**.
-The Gateway will subscribe to the "response" topic and wait for a device reply until "responseTimeout" is reached (in milliseconds).
-
-Here is an example of an RPC request (rpc-request.json) that needs to be sent from the server:
-
-```json
-{
- "method": "echo",
- "params": {
- "message": "Hello!"
- }
-}
-```
-
-Also, every telemetry and attribute parameter has built-in GET and SET RPC methods out of the box, so you don’t need to configure
-it manually. To use them, make sure you set all the required parameters (in the case of MQTT Connector, these are the following:
-**request topic expression**, **response topic expression**, **response timeout**, **value expression**).
-See [the guide](/docs/iot-gateway/guides/how-to-use-get-set-rpc-methods).
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/workers-settings-section-advanced.md b/_includes/templates/iot-gateway/mqtt-connector/workers-settings-section-advanced.md
deleted file mode 100644
index e9fe8ca5b1..0000000000
--- a/_includes/templates/iot-gateway/mqtt-connector/workers-settings-section-advanced.md
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-- **maxNumberOfWorkers** is a maximal number of workers thread for converters (amount of workers changes dynamically, depending on load). Recommended amount 50-100;
-- **maxMessageNumberPerWorker** is a maximal messages count that will be in queue for each converter worker.
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/mqtt-connector/workers-settings-section-basic.md b/_includes/templates/iot-gateway/mqtt-connector/workers-settings-section-basic.md
index 4f70ab5c2f..a4dd1d32c8 100644
--- a/_includes/templates/iot-gateway/mqtt-connector/workers-settings-section-basic.md
+++ b/_includes/templates/iot-gateway/mqtt-connector/workers-settings-section-basic.md
@@ -1,5 +1,9 @@

-**Max number of workers** is a maximal number of workers thread for converters (amount of workers changes dynamically, depending on load). Recommended amount 50-100.
+1. **Max messages queue per worker**
+How many MQTT messages one worker handles in a single turn before letting others run.
+Bigger number = higher throughput; smaller = lower latency. Example: ~100 for heavy telemetry, ~10–20 for fast RPC.
-**Max messages queue per worker** is a maximal messages count that will be in queue for each converter worker.
\ No newline at end of file
+2. **Max number of workers**
+How many workers run at the same time. More workers use more CPU cores but can cause contention if too high.
+Start near your CPU core count and tweak based on backlog and CPU.
\ No newline at end of file
diff --git a/_includes/templates/iot-gateway/opcua-connector/examples/shared-attributes-rpc/shared-attributes-with-absolute-path.md b/_includes/templates/iot-gateway/opcua-connector/examples/shared-attributes-rpc/shared-attributes-with-absolute-path.md
index 25070b82ba..e5bbc87756 100644
--- a/_includes/templates/iot-gateway/opcua-connector/examples/shared-attributes-rpc/shared-attributes-with-absolute-path.md
+++ b/_includes/templates/iot-gateway/opcua-connector/examples/shared-attributes-rpc/shared-attributes-with-absolute-path.md
@@ -18,7 +18,7 @@ Let's add an attribute update to our configuration. For this purpose, follow the
{% assign attributeUpdatesAbsolutePath = '
===
image: /images/gateway/opc-ua-connector/examples/device-name-and-profile-absolute-path-1.png,
- title: Go to "**Entities**" → "**Gateways**" in the right sidebar and select your gateway.
+ title: Go to "**Entities**" → "**Gateways**" in the left sidebar and select your gateway.
===
image: /images/gateway/opc-ua-connector/examples/device-name-and-profile-absolute-path-2.png,
title: Click on the "**Connectors configuration**" button on the right side menu.
diff --git a/_includes/templates/iot-gateway/socket-connector/device-time-series-and-attributes-basic-section.md b/_includes/templates/iot-gateway/socket-connector/device-time-series-and-attributes-basic-section.md
index 52cb956446..89ab2b06d5 100644
--- a/_includes/templates/iot-gateway/socket-connector/device-time-series-and-attributes-basic-section.md
+++ b/_includes/templates/iot-gateway/socket-connector/device-time-series-and-attributes-basic-section.md
@@ -32,7 +32,7 @@ data is sent to the ThingsBoard server. The following strategies are available:
- **On report period** - sends data to ThingsBoard after the report period;
- **On value change** - sends data to ThingsBoard when the value changes;
-- **On value change and report period** - sends data to ThingsBoard when the value changes or report period;
+- **On value change or report period** - sends data to ThingsBoard when the value changes or report period;
- **On received** - sends data to ThingsBoard after receiving data from the device (default strategy).

diff --git a/_includes/templates/iot-gateway/upgrade-instructions/alma-rhel-server.md b/_includes/templates/iot-gateway/upgrade-instructions/alma-rhel-server.md
new file mode 100644
index 0000000000..3cd7aaad22
--- /dev/null
+++ b/_includes/templates/iot-gateway/upgrade-instructions/alma-rhel-server.md
@@ -0,0 +1,72 @@
+### Step 1. Download the `.rpm` file
+
+Download installation `.rpm` package.
+
+```bash
+wget https://github.com/thingsboard/thingsboard-gateway/releases/latest/download/python3-thingsboard-gateway.rpm
+````
+{: .copy-code}
+
+### Step 2. Install the new `.rpm` file
+
+Run the following command in the terminal to install the updated package:
+
+```bash
+sudo dnf install -y ./python3-thingsboard-gateway.rpm
+```
+{: .copy-code}
+
+{% capture difference %}
+This will automatically upgrade your existing Gateway installation without removing your configuration and
+extension files **(from Gateway version 3.7.6)**.
+{% endcapture %}
+{% include templates/info-banner.md content=difference %}
+
+{% capture difference1 %}
+If you are upgrading from a gateway version lower than 3.7.6, make backups of your configuration and extension files.
+{% endcapture %}
+{% include templates/warn-banner.md content=difference1 %}
+
+### Step 3. Restart the Gateway
+
+After the upgrade, restart the Gateway service to apply the changes:
+
+```bash
+sudo systemctl restart thingsboard-gateway
+```
+{: .copy-code}
+
+### Step 4. Verify the Upgrade
+
+To ensure the upgrade was successful, check the Gateway status and logs by running:
+
+```bash
+sudo systemctl status thingsboard-gateway
+```
+{: .copy-code}
+
+### Configuration File Preservation
+
+During the upgrade, **all user configuration files will be preserved.** This includes customizations made to:
+- Connector configuration files.
+- Custom user extensions.
+- `tb_gateway.json` file.
+
+The upgrade process also automatically creates a backup of your current configuration directory to ensure
+recoverability in case of any issues. The backups are stored under the following paths:
+
+- For connector configurations:
+ ```
+ /etc/thingsboard-gateway/configs_backup.tar.gz
+ ```
+
+- For user extensions:
+ ```
+ /var/lib/thingsboard_gateway/extensions_backup.tar.gz
+ ```
+
+### Notes
+
+- This upgrade procedure applies only to .rpm package-based installations. If you are using Docker or pip-based
+ installations, please refer to the appropriate guide that you can find on the top of this page.
+- Always test the Gateway after the upgrade to ensure connectors and extensions operate as expected.
diff --git a/_includes/templates/iot-gateway/upgrade-instructions/cent-rhel-server.md b/_includes/templates/iot-gateway/upgrade-instructions/cent-rhel-server.md
deleted file mode 100644
index a97a235967..0000000000
--- a/_includes/templates/iot-gateway/upgrade-instructions/cent-rhel-server.md
+++ /dev/null
@@ -1,72 +0,0 @@
-### Step 1. Download the `.rpm` file
-
-Download installation `.rpm` package.
-
-```bash
-wget https://github.com/thingsboard/thingsboard-gateway/releases/latest/download/python3-thingsboard-gateway.rpm
-````
-{: .copy-code}
-
-### Step 2. Install the new `.rpm` file
-
-Run the following command in the terminal to install the updated package:
-
-```bash
-sudo yum install -y ./python3-thingsboard-gateway.rpm
-```
-{: .copy-code}
-
-{% capture difference %}
-This will automatically upgrade your existing Gateway installation without removing your configuration and
-extension files **(from Gateway version 3.7.6)**.
-{% endcapture %}
-{% include templates/info-banner.md content=difference %}
-
-{% capture difference1 %}
-If you are upgrading from a gateway version lower than 3.7.6, make backups of your configuration and extension files.
-{% endcapture %}
-{% include templates/warn-banner.md content=difference1 %}
-
-### Step 3. Restart the Gateway
-
-After the upgrade, restart the Gateway service to apply the changes:
-
-```bash
-sudo systemctl restart thingsboard-gateway
-```
-{: .copy-code}
-
-### Step 4. Verify the Upgrade
-
-To ensure the upgrade was successful, check the Gateway status and logs by running:
-
-```bash
-sudo systemctl status thingsboard-gateway
-```
-{: .copy-code}
-
-### Configuration File Preservation
-
-During the upgrade, **all user configuration files will be preserved.** This includes customizations made to:
-- Connector configuration files.
-- Custom user extensions.
-- `tb_gateway.json` file.
-
-The upgrade process also automatically creates a backup of your current configuration directory to ensure
-recoverability in case of any issues. The backups are stored under the following paths:
-
-- For connector configurations:
- ```
- /etc/thingsboard-gateway/configs_backup.tar.gz
- ```
-
-- For user extensions:
- ```
- /var/lib/thingsboard_gateway/extensions_backup.tar.gz
- ```
-
-### Notes
-
-- This upgrade procedure applies only to .rpm package-based installations. If you are using Docker or pip-based
- installations, please refer to the appropriate guide that you can find on the top of this page.
-- Always test the Gateway after the upgrade to ensure connectors and extensions operate as expected.
diff --git a/_includes/templates/live-demo-banner.md b/_includes/templates/live-demo-banner.md
index a247e0805a..5e0270fa2a 100644
--- a/_includes/templates/live-demo-banner.md
+++ b/_includes/templates/live-demo-banner.md
@@ -1,5 +1,5 @@
{% capture liveDemoContent %}
-We recommend to use [**ThingsBoard Cloud**](https://{{hostName}}/signup) - fully managed, scalable and fault-tolerant platform for your IoT applications
+We recommend to use [**ThingsBoard Cloud**](https://thingsboard.io/products/paas/) - fully managed, scalable and fault-tolerant platform for your IoT applications
ThingsBoard Cloud is for everyone who would like to use ThingsBoard but don’t want to host their own instance of the platform.
{% endcapture %}
{% include templates/info-banner.md title="ThingsBoard Cloud" content=liveDemoContent %}
diff --git a/_includes/templates/prerequisites-pe.md b/_includes/templates/prerequisites-pe.md
index 28fcea4cec..4b3171bf71 100644
--- a/_includes/templates/prerequisites-pe.md
+++ b/_includes/templates/prerequisites-pe.md
@@ -1,4 +1,8 @@
## Prerequisites
-You will need access to ThingsBoard Professional Edition. The easiest way is to use [ThingsBoard Cloud](https://{{hostName}}/signup){:target="_blank"} server.
-Alternatively, you can install ThingsBoard using the [installation guide](/docs/user-guide/install/pe/installation-options/){:target="_blank"}.
\ No newline at end of file
+You will need access to ThingsBoard Professional Edition. The easiest option is to use a [ThingsBoard Cloud](/installations/choose-region/){:target="_blank"} server.
+
+Alternatively, you can install ThingsBoard yourself using our [installation guides](/docs/user-guide/install/pe/installation-options/){:target="_blank"}:
+
+- For **Windows** users, follow this [installation guide](/docs/user-guide/install/pe/docker-windows/){:target="_blank"}.
+- For **Linux** and **MacOS** users, follow this [installation guide](/docs/user-guide/install/pe/docker/){:target="_blank"}.
\ No newline at end of file
diff --git a/_includes/templates/prerequisites.md b/_includes/templates/prerequisites.md
index 86d6b7add3..25094b60c5 100644
--- a/_includes/templates/prerequisites.md
+++ b/_includes/templates/prerequisites.md
@@ -1,26 +1,9 @@
## Prerequisites
-You will need to have ThingsBoard server up and running.
-The easiest way is to use [Live Demo](https://demo.thingsboard.io/signup){:target="_blank"} server.
+You will need a ThingsBoard server up and running.
+The easiest way to get started is with the [Live Demo](https://demo.thingsboard.io/signup){:target="_blank"} server.
-The alternative option is to install ThingsBoard using the [installation guide](/docs/user-guide/install/installation-options/){:target="_blank"}:
-- **Windows** users should follow this [guide](/docs/user-guide/install/docker-windows/){:target="_blank"}
-- **Linux** users with Docker installed can execute the following commands:
+Alternatively, you can install ThingsBoard yourself using our [installation guides](/docs/user-guide/install/installation-options/){:target="_blank"}:
-```
-mkdir -p ~/.mytb-data && sudo chown -R 799:799 ~/.mytb-data
-mkdir -p ~/.mytb-logs && sudo chown -R 799:799 ~/.mytb-logs
-docker run -it -p 8080:9090 -p 7070:7070 -p 1883:1883 -p 5683-5688:5683-5688/udp -v ~/.mytb-data:/data \
--v ~/.mytb-logs:/var/log/thingsboard --name mytb --restart always thingsboard/tb-postgres
-```
-{: .copy-code}
-
-These commands install ThingsBoard and load demo data and accounts.
-
-The ThingsBoard UI will be available at: **http://localhost:8080**.
-
-You can use:
-- Username: **tenant@thingsboard.org**
-- Password: **tenant**
-
-[More information about the demo account](/docs/samples/demo-account/){:target="_blank"}.
\ No newline at end of file
+- For **Windows** users, follow this [installation guide](/docs/user-guide/install/docker-windows/){:target="_blank"}.
+- For **Linux** and **MacOS** users, follow this [installation guide](/docs/user-guide/install/docker/){:target="_blank"}.
\ No newline at end of file
diff --git a/_includes/templates/ssl/certificates-chain.md b/_includes/templates/ssl/certificates-chain.md
index 69808f1905..686f332a77 100644
--- a/_includes/templates/ssl/certificates-chain.md
+++ b/_includes/templates/ssl/certificates-chain.md
@@ -103,7 +103,7 @@ An optional company name []:
To generate the intermediate certificate, use the following command. Don't forget to put the correct CN when prompted:
```bash
-openssl x509 -req -in intermediate.csr -out intermediateCert.pem -CA rootCert.pem -CAkey rootKey.pem -days 365 -sha256 -CAcreateserial
+openssl x509 -req -in intermediate.csr -out intermediateCert.pem -CA rootCert.pem -CAkey rootKey.pem -days 365 -sha256 -CAcreateserial -extfile <(echo "basicConstraints=CA:TRUE")
```
{: .copy-code}
diff --git a/_includes/templates/trndz-guides-banner.md b/_includes/templates/trndz-guides-banner.md
index 9a709b9c94..d5571ebe80 100644
--- a/_includes/templates/trndz-guides-banner.md
+++ b/_includes/templates/trndz-guides-banner.md
@@ -4,8 +4,14 @@
{% if currentGuide != "InstallationOptions" %}
- [**Installation guides**](/docs/trendz/install/installation-options/) - Learn how to setup ThingsBoard on various available operating systems.
{% endif %}
+{% if currentGuide != "MetricExplorer" %}
+- [**Metric Explorer**](/docs/trendz/metric/overview) - Learn how to explore and create new metrics with Trendz Metric Explorer.
+{% endif %}
+{% if currentGuide != "AnomalyDetection" %}
+- [**Anomaly Detection**](/docs/trendz/anomaly/overview) - Learn how to identify anomalies in the data.
+{% endif %}
{% if currentGuide != "CalculatedFields" %}
-- [**Calculated Fields**](/docs/trendz/calculated-fields) - Learn about Calculated fields and how to use them.
+- [**Calculated Fields**](/docs/trendz/calculations/overview) - Learn about Calculated fields and how to use them.
{% endif %}
{% if currentGuide != "States" %}
- [**States**](/docs/trendz/states) - Learn how to define and analyse states for assets based on raw telemetry.
@@ -13,9 +19,6 @@
{% if currentGuide != "Prediction" %}
- [**Prediction**](/docs/trendz/prediction) - Learn how to make forecasts and predict telemetry behavior.
{% endif %}
-{% if currentGuide != "AnomalyDetection" %}
-- [**Anomaly Detection**](/docs/trendz/anomaly/overview.md) - Learn how to identify anomalies in the data.
-{% endif %}
{% if currentGuide != "Filtering" %}
- [**Filters**](/docs/trendz/data-filtering) - Learn how filter dataset during analysis.
{% endif %}
diff --git a/_includes/tocsearch.html b/_includes/tocsearch.html
index 38587a21a4..1caf289e6c 100644
--- a/_includes/tocsearch.html
+++ b/_includes/tocsearch.html
@@ -1 +1 @@
-{% for item in tree %}{% if item.section %}{% assign tree = item.section %}{% include tocsearch.html %}{% else %}{% if item.path == page.url %}{% assign foundTOC = thistoc %}{% assign title = item.title %}{% break %}{% endif %}{% endif %}{% endfor %}
\ No newline at end of file
+{%- assign effectiveUrl = page.url -%}{%- if page.url contains '/releases-table/' -%}{%- if page.url contains '/pe/' -%}{%- assign effectiveUrl = '/docs/pe/releases/releases-table/' -%}{%- else -%}{%- assign effectiveUrl = '/docs/releases/releases-table/' -%}{%- endif -%}{%- endif -%}{%- if page.url contains '/upgrade-instructions/' -%}{%- if page.url contains '/pe/' -%}{%- assign effectiveUrl = '/docs/pe/user-guide/install/upgrade-instructions/' -%}{%- else -%}{%- assign effectiveUrl = '/docs/user-guide/install/upgrade-instructions/' -%}{%- endif -%}{%- endif -%}{%- for item in tree -%}{%- if item.section -%}{%- assign tree = item.section -%}{%- include tocsearch.html -%}{%- if foundTOC -%}{%- break -%}{%- endif -%}{%- else -%}{%- if item.path == effectiveUrl -%}{%- assign foundTOC = thistoc -%}{%- assign title = item.title -%}{%- break -%}{%- endif -%}{%- endif -%}{%- endfor -%}
\ No newline at end of file
diff --git a/_includes/upgrade-instructions-table.liquid b/_includes/upgrade-instructions-table.liquid
new file mode 100644
index 0000000000..9e02b3a2e5
--- /dev/null
+++ b/_includes/upgrade-instructions-table.liquid
@@ -0,0 +1,208 @@
+{% assign versionsCollection = site.data.upgrade-unstructions-table %}
+
+
Dive into the technical aspects of IoT development and programming. From beginner guides to advanced tutorials, this category offers resources for developers interested in creating applications, firmware, and software solutions for IoT devices. Explore coding techniques, programming languages, and development frameworks tailored to the IoT ecosystem.
From Architecture to Results: Why Working with the Platform Team Makes a Difference
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
When you’re, as a company or system integrator, looking to implement an IoT solution, you usually face three options: build it in-house, fully outsource, or co-build it with a platform team (like the one behind ThingsBoard).
+
+
+
+
Building in-house works well if you already have senior IoT architects and a long project runway. Outsourcing, on the other hand, may be suitable for a quick, low-stakes PoC. But for most companies, the most balanced choice is partnering with a platform team.
+
+
+
+
If time-to-value, reliability, and future scalability are your top priorities, a platform team gives you the shortest path to an MVP, reduces overall risk, and ensures real knowledge transfer instead of leaving you with a “black box” solution. In short, it’s the most direct way to get from architecture to results.
+
+
+
+
+
+
+
+
+
+
One solution – 3 delivery models. What do they mean?
+
+
+
+
+
+
+
In-House Development
+
+
+
+
This model works best for companies that already have experienced IoT architects and engineers on staff, and can afford a long runway of 12–18 months.
+
+
+
+
+
+
Pros: You get full control over the architecture and code, clear cost visibility, and retain direct intellectual property ownership. Pitfalls: IoT projects demand expertise across multiple domains — from device connectivity and over-the-air (OTA) updates to security, rule chains, and performance scaling. Without prior IoT experience, your team can hit a talent bottleneck. The learning curve alone may take 3–12 months, turning the initiative into a slow and risky process.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Traditional Outsourcing
+
+
+
+
A solid choice if you need a quick demo, a narrowly scoped solution, or a project without a long-term roadmap.
+
+
+
+
+
+
Pros: Rapid access to engineers and flexible resourcing without lengthy hiring processes. Pitfalls: The expertise of a third-party vendor in your specific IoT domain can vary wildly. Their business model often skews toward selling developer hours, not finishing a project faster. As a result, what looks like an attractive hourly rate can hide a much higher Total Cost of Ownership (TCO) due to rework, missed requirements, and costly fixes. They also often rebuild common plumbing from scratch, which wastes both time and budget.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Working with a Platform Team
+
+
+
+
For anyone who needs acceleration of IoT project, with built-in security and an eye toward future requirements, collaborating with an IoT development service by platform is the most balanced choice. This means working directly with the team that built and lives in the platform.
+
+
+
+
+
+
Pros: Deep platform knowledge ensures optimal implementation choices from day one, leading to predictable architecture and a shorter time to market. Engagements follow proven accelerators and patterns, with structured knowledge transfer to your team. Pitfalls: Some companies worry about “vendor lock-in,” but this risk is mitigated by open APIs and documented extension points. While day rates may appear higher, the overall TCO is typically lower thanks to reduced delivery time and minimized risk of costly rewrites.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Explore how our custom IoT development accelerates results
Deciding on the right development model isn’t about guesswork, it’s about a structured evaluation of what matters most to your business. The most effective way to do this is by creating a scorecard. Review the following criteria and assess each model (in-house, outsourcing, or platform team) against the priorities of your project.
+
+
+
+
+
+
+
+
+
+
+
+
+
Time-to-MVP / Time-to-Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
How critical is it to launch a minimum viable product quickly? A predictable delivery schedule often outweighs the appeal of a lower hourly rate.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Total Cost of Ownership (TCO)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Look beyond the initial build cost. Factor in long-term expenses such as infrastructure, licenses, support, training, and maintenance. A low upfront investment can mask a much higher long-term cost.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Architecture Quality
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Will the IoT solution be easy to maintain and extend? Does it align with your long-term product roadmap?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Scalability & Performance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
What are your throughput goals? How many devices and messages per second must be supported? Will the solution meet your p95/p99 latency requirements?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Security & Compliance
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Are there strict requirements for data residency, auditability, and access control (RBAC)? This is a non-negotiable for many industries.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Talent Availability
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Do you already have senior IoT architects and engineers with IoT related topics (scaling, security, OTA, etc.) expertise in-house? If not, building from scratch poses a significant talent risk.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Vendor Lock-in & IP Ownership
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
How important is it for you to own every line of code? Assess the portability of the solution and whether its APIs are open and well-documented.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Lifecycle Support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Who will run and maintain the solution in 3, 5, or even 10 years? What’s the plan if a core engineer leaves the team?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Integration Complexity
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ How easily will the solution connect with your existing systems, such as ERP/CRM, data lakes, or streaming services like Kafka?
+
+
+
+
+
+
+
+
+
If your project’s success depends on time-to-value, built-in security, and future scalability, the scorecard will almost always favor the Platform Team. It’s the path that delivers production-grade results quickly while protecting your long-term architectural integrity.
+
+
+
+
+
+
The economics: comparing rates vs. total cost of ownership
+
+
+
+
+
+
When weighing development models, it’s tempting to focus on one metric: the hourly rate. An outsourced team might advertise a lower rate, but that figure is often misleading. In practice, you may be paying for engineers who are learning your domain on the job and reinventing “plumbing” that others have already solved. The result? Longer timelines and significant hidden costs increase the total cost of ownership (TCO).
+
+
+
+
Platform teams, by contrast, may come with a higher hourly rate, but their economics work differently. They rely on mature templates, proven accelerators, and established architectural patterns that compress delivery time and minimize rework. In one internal benchmark for a warehouse monitoring project, the platform team delivered a production-grade solution 5–9x faster and cheaper than alternative approaches.
+
+
+
+
The bottom line is simple: don’t optimize for hourly/daily rates. Instead, focus on the total cost of ownership. The goal is a production-ready MVP delivered in weeks, with clear extensibility and defined Service Level Objectives (SLOs). A platform team’s model is designed to achieve these results with maximum efficiency, making it the more cost-effective choice in the long run.
+
+
+
+
+
+
KPIs that prove it worked
+
+
+
+
+
How do you know you made the right choice? It’s not about opinions – it’s about measurable results. The true proof of success lies in KPIs that reflect both technical excellence and business value.
+
+
+
+
Here are the metrics that matter:
+
+
+
+
+
+Lead time to first device online – days from project start to the first device sending data. A short lead time proves setup efficiency.
+
+
+
+
+Time to MVP – weeks to deliver a production-ready solution with defined critical flows. The ultimate speed benchmark.
+
+
+
+
+Throughput & latency – performance under load, measured by target messages per second and p95 latency.
+
+
+
+
+Uptime & reliability – track uptime against SLOs and monitor Mean Time to Repair (MTTR). This defines operational resilience.
+
+
+
+
+Cost per connected device – a clear view of long-term economics, including build costs and ongoing operations.
+
+
+
+
+Development efficiency – percentage of flows built with reusable rule-chain blocks. Shows how well the platform accelerates delivery.
+
+
+
+
+Integration reliability – success rate of ERP/CRM integrations, retry depth, and dead-letter messages. Proof that data flows are consistent and lossless.
+
+
+
+
+
The takeaway: Tracking these KPIs gives you a data-driven view of success. They prove that making strong architectural choices translates directly into faster delivery, lower costs, and more reliable IoT operations.
+
+
+
+
+
+
A mini case study: pattern, not hype
+
+
+
+
+
Talking about frameworks and KPIs is useful — but seeing them in action is better. Here’s a real-world example that shows how a platform-based approach delivers results.
+
+
+
+
Context A large-scale warehouse monitoring project with tens of thousands of sensors. The requirement: track environmental parameters in real time and trigger instant alerts when thresholds were exceeded.
+
+
+
+
+
+
Approach The team used ThingsBoard Professional Edition as the foundation.
+
+
+
+
+
+MQTT handled device data ingestion.
+
+
+
+
+Cassandra ensured efficient hot data storage.
+
+
+
+
A proven “ingest→validate→enrich→route→DLQ” rule-chain template cut down implementation time.
+
+
+
+
+Kafka bridge enabled smooth integration with an existing data lake.
+
+
+
+
+
OTA updates kept firmware management under control.
+
+
+
+
+
+
Outcome The impact of the collaboration was immediately noticeable:
+
+
+
+
+
+MVP delivered in 6 weeks — far ahead of industry averages.
+
+
+
+
+p95 alert time under 10 seconds, even at scale.
+
+
+
+
Operator dashboards were live from day one.
+
+
+
+
+
Adding new warehouses required only minimal effort.
+
+
+
+
+
+
(Note: Metrics are based on an internal reference project. Actual results will depend on scope and constraints.)
+
+
+
+
The takeaway: This isn’t hype – it’s a repeatable pattern. By combining a proven platform with a team that knows it inside out, you skip months of groundwork and move straight to production-grade results: faster launches, lower risk, and scalable architecture.
+
+
+
+
+
+
+
Get your free consultation and start building your IoT solution
Risks & mitigations: be honest about the challenges
+
+
+
+
+
Every IoT project carries risks. Success depends not on pretending they don’t exist, but on recognizing them early and putting mitigation strategies in place. Here are the most common challenges and how to manage them effectively:
+
+
+
+
1. Scope Creep Projects can easily expand beyond their original intent. Mitigation: use time-boxed epics, a formal change control process, and a transparent backlog with clear business acceptance criteria. This discipline keeps the focus on what matters most.
+
+
+
+
2. Performance Surprises Discovering too late that your system can’t handle the load is costly. Mitigation: start with a capacity model (devices, messages/sec, payload size). Run load tests early and configure autoscaling based on live metrics like queue depth.
+
+
+
+
3. Vendor Lock-in A valid concern with platform-based approaches. Mitigation: secure IP ownership in your contract, keep all code in your repositories, and rely on platforms with open APIs, documented extension points, and a clear exit plan.
+
+
+
+
4. Security Gaps Security isn’t a “nice-to-have”, it’s foundational. Mitigation: apply threat modeling and least-privilege access. Rotate credentials periodically and ensure all changes are logged and auditable.
+
+
+
+
5. Knowledge Loss A solution is only sustainable if your team can own it long-term. Mitigation: make enablement part of the deliverables. Use pair programming, recorded code reviews, and living architecture documentation. Ensure your team leaves with the runbooks and knowledge to operate the system independently.
+
+
+
+
+
+
Rules of thumb: when each model fits
+
+
+
+
+
Ultimately, the best choice depends on your specific situation. There’s no one-size-fits-all answer, but you can use these simple rules of thumb to guide your decision:
+
+
+
+
Go In-House When you already have senior IoT architects, proven platform expertise, and a generous project runway of 12–18 months.
+
+
+
+
Go Outsourcing For a short-lived Proof of Concept (PoC) with a narrow scope and no long-term roadmap—ideally with a vendor who has already solved something very similar in your niche.
+
+
+
+
Go Platform Team When you need production-grade results fast, expect your backlog to evolve, and want your internal team to be enabled and empowered—not sidelined.
+
+
+
+
By following these guidelines, you can match your development model with your business goals and set your project up for success from the very beginning.
+
+
+
+
+
+
In conclusion
+
+
+
+
+
There is no “one-size-fits-all” solution for every IoT project. The right choice depends on your specific needs, resources, and long-term goals. If you have deep, in-house IoT expertise and plenty of time, building it yourself is a great option. If all you need is a quick demo or a short-lived proof of concept, outsourcing can get the job done.
+
+
+
+
But for the majority of businesses, where production results, time-to-value, and future scalability are non-negotiable, the most balanced choice is to work with a platform’s IoT development company. This approach not only gets you to market faster with a reliable, scalable solution, but it also empowers your own team with the knowledge they need to own the solution for the long haul. It’s an investment in a product and your people.
+
+
+
+
+
+
+
+
+ Sign up today and discover what ThingsBoard Cloud can do for you!
+
Introducing ThingsBoard MCP 2.0: Powerful New Query & Write Tools for ThingsBoard Platform
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Version 2.0 – major release – bringing new capabilities for advanced data access and management
+
+
+
+
Imagine not only asking your ThingsBoard platform questions like “Show me all gateways that reported offline in the last hour” or “List alarms for device X and their severities” (as we did in version 1.0) but now also running complex queries across entities, writing or updating devices, assets, alarms, users and more – all via a unified protocol. With ThingsBoard MCP 2.0 that vision becomes reality.
+
+
+
+
What’s new in 2.0
+
+
+
+
We’ve pushed the envelope in this major release with two big themes: expanded data query capabilities, and full write-operation support across key entity types. On top of that, we’ve addressed important bug-fixes for better reliability.
+
+
+
+
Major Features
+
+
+
+
Entity Data Query Tools
+
+
+
+
+
You can now run complex queries over entities, their fields, attributes and telemetry, and retrieve structured data sets for advanced analytics workflows.
+
+
+
+
Whether you’re looking across devices, assets, customers, relations or user entities, the new query tools let you filter, join, aggregate and extract exactly the data you need.
+
+
+
+
Ideal for data scientists, analytics engineers and anyone building reports or dashboards that go beyond simple telemetry lookups.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Write Operations Support We’ve added full write-capability (create/update/delete) across a broad set of entity types:
+
+
+
+
+
Devices
+
+
+
+
Assets
+
+
+
+
Alarms
+
+
+
+
Customers
+
+
+
+
Relations
+
+
+
+
Users
+
+
+
+
Entity Groups (PE tools)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Now you can not only query what’s happening in your IoT environment, but also act on it programmatically via the MCP interface. This is a real step toward end-to-end automation, self-service operations, and AI-driven workflows.
+
+
+
+
Minor Fixes & Improvements
+
+
+
+
+
Fixed the “get telemetry” tool to correctly fetch values when using aggregation functions – ensuring that average, sum, min/max or custom aggregation operations now return expected data.
+
+
+
+
Other miscellaneous stability and performance enhancements across the core MCP modules (internal housekeeping, improved logging, better error messages) to make version 2.0 a robust platform.
+
+
+
+
+
Why this matters
+
+
+
+
With version 1.0, ThingsBoard MCP gave users conversational, AI-assistant friendly access to devices, telemetry, attributes and relationships. ThingsBoard MCP Version 2.0 takes the next leap:
+
+
+
+
+
+Deeper analytics: The new query tools enable you to treat your IoT platform as a rich data source, not just a telemetry repository. You can ask for cross-entity insights, complex attribute/field filters, aggregated telemetry results, and more.
+
+
+
+
+Actionable workflows: With write support across devices, assets, alarms, users, etc., you’re not just reading data – you’re controlling and managing your environment. That’s automation, orchestration and AI-enabled operations unlocked.
+
+
+
+
+Reduced development overhead: Rather than building bespoke APIs or middleware to handle queries + writes, ThingsBoard MCP 2.0 provides a unified abstraction layer. Developers, data engineers and non-technical users all benefit.
+
+
+
+
+
Getting started
+
+
+
+
Here’s how to upgrade and unlock the new features:
+
+
+
+
+
+Upgrade your MCP server – Pull or build the version 2.0 image (or JAR) from the official repository.
+
+
+
+
+Review your configuration – Ensure your MCP config (e.g., in Claude Desktop or other LLM tool integrations) points to the refreshed endpoint. If you are using write-capabilities, review and adjust your permissions/security settings accordingly.
+
+
+
+
+Explore the query tools – Use the new query-API to run entity data queries. Try filtering devices by multiple attributes, joining asset with telemetry, or filtering device by combination of entity name, device type and attribute value.
+
+
+
+
+Test write operations – Try creating or updating a device, asset or alarm through the MCP interface. Verify you can manipulate relations and entity groups as needed.
+
+
+
+
+
Full reference docs for version 2.0 (query syntax, write-API endpoints, permissions model, examples) are available in the GitHub repository.
+
+
+
+
Use-cases in focus
+
+
+
+
Here are a few real-world scenarios where MCP 2.0 opens up new possibilities:
+
+
+
+
+
+Predictive maintenance analytics: Run a query to fetch all devices of type “pump” in location “Site-A” whose vibration telemetry shows increasing trend then create a maintenance work-order (via write operation) for those devices.
+
+
+
+
+Large-scale device onboarding: Use write tools to bulk create or update devices, assign them to customers or assets, set up their relations and initial attributes – all via MCP rather than manual UI or REST API scripting.
+
+
+
+
+Automated alarm handling: Query all active alarms above a certain severity threshold, update their status, trigger notifications or escalate to customer account managers – seamlessly from “ask a question” to “perform an action.”
+
+
+
+
+Self-service analytics for non-dev users: A business-analyst can use the query tool to extract a dataset of asset usage metrics across customers, download the results and feed into their BI tool – without writing SQL or custom API code.
+
+
+
+
+
Thank you
+
+
+
+
We’d like to thank our community and early adopters who provided invaluable feedback. Your use-cases, bug-reports and feature requests help shape MCP’s roadmap. Please try ThingsBoard MCP 2.0, report any issues, and share your automation and analytics success stories with us.
+
+
+
+
Get started now — Visit the GitHub repository and check the release notes for version 2.0. Let’s make your ThingsBoard IoT platform more conversational, actionable and intelligent!
+
+
+
+
+
+
+
+
+
+
+
+
+ Sign up today and discover what ThingsBoard Cloud can do for you!
+