From dba362891682fc66606581cdcc466ced713e4fdd Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Thu, 27 Aug 2026 11:12:57 +0300 Subject: [PATCH 1/2] Add assign/unassign entity group to edge rule node docs --- astro.sidebar.ts | 4 + public/redirects.json | 10 ++ .../reference/rule-engine/nodes/action.mdx | 2 + .../action/assign-entity-group-to-edge.mdx | 153 ++++++++++++++++++ .../unassign-entity-group-from-edge.mdx | 129 +++++++++++++++ .../action/assign-entity-group-to-edge.mdx | 8 + .../unassign-entity-group-from-edge.mdx | 8 + .../action/assign-entity-group-to-edge.mdx | 8 + .../unassign-entity-group-from-edge.mdx | 8 + .../action/assign-entity-group-to-edge.mdx | 8 + .../unassign-entity-group-from-edge.mdx | 8 + .../action/assign-entity-group-to-edge.mdx | 8 + .../unassign-entity-group-from-edge.mdx | 8 + .../action/assign-entity-group-to-edge.mdx | 8 + .../unassign-entity-group-from-edge.mdx | 8 + .../action/assign-entity-group-to-edge.mdx | 8 + .../unassign-entity-group-from-edge.mdx | 8 + 17 files changed, 394 insertions(+) create mode 100644 src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx create mode 100644 src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx create mode 100644 src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx create mode 100644 src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx create mode 100644 src/content/docs/docs/edge/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx create mode 100644 src/content/docs/docs/edge/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx create mode 100644 src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx create mode 100644 src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx create mode 100644 src/content/docs/docs/paas/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx create mode 100644 src/content/docs/docs/paas/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx create mode 100644 src/content/docs/docs/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx create mode 100644 src/content/docs/docs/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx create mode 100644 src/content/docs/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx create mode 100644 src/content/docs/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx diff --git a/astro.sidebar.ts b/astro.sidebar.ts index 130b5974b7..9fd079307e 100644 --- a/astro.sidebar.ts +++ b/astro.sidebar.ts @@ -665,6 +665,7 @@ const paasReferenceItems = (prefix: string): SidebarConfig => { items: [ { label: 'Overview', slug: `${prefix}/rule-engine/nodes/action` }, `${prefix}/rule-engine/nodes/action/add-to-group`, + `${prefix}/rule-engine/nodes/action/assign-entity-group-to-edge`, `${prefix}/rule-engine/nodes/action/assign-to-customer`, `${prefix}/rule-engine/nodes/action/calculated-fields`, `${prefix}/rule-engine/nodes/action/change-owner`, @@ -694,6 +695,7 @@ const paasReferenceItems = (prefix: string): SidebarConfig => { `${prefix}/rule-engine/nodes/action/save-attributes`, `${prefix}/rule-engine/nodes/action/save-timeseries`, `${prefix}/rule-engine/nodes/action/save-to-custom-table`, + `${prefix}/rule-engine/nodes/action/unassign-entity-group-from-edge`, `${prefix}/rule-engine/nodes/action/unassign-from-customer`, ], }, @@ -1252,6 +1254,7 @@ const referenceItems = (prefix: string, extraConfigItems: SidebarConfig = []) => items: [ { label: 'Overview', slug: `${prefix}/rule-engine/nodes/action` }, `${prefix}/rule-engine/nodes/action/add-to-group`, + `${prefix}/rule-engine/nodes/action/assign-entity-group-to-edge`, `${prefix}/rule-engine/nodes/action/assign-to-customer`, `${prefix}/rule-engine/nodes/action/calculated-fields`, `${prefix}/rule-engine/nodes/action/change-owner`, @@ -1281,6 +1284,7 @@ const referenceItems = (prefix: string, extraConfigItems: SidebarConfig = []) => `${prefix}/rule-engine/nodes/action/save-attributes`, `${prefix}/rule-engine/nodes/action/save-timeseries`, `${prefix}/rule-engine/nodes/action/save-to-custom-table`, + `${prefix}/rule-engine/nodes/action/unassign-entity-group-from-edge`, `${prefix}/rule-engine/nodes/action/unassign-from-customer`, ], }, diff --git a/public/redirects.json b/public/redirects.json index dbfcc68d62..273d2a6bbe 100644 --- a/public/redirects.json +++ b/public/redirects.json @@ -1267,6 +1267,7 @@ "/docs/paas/recipes/": "/docs/paas/user-guide/", "/docs/paas/eu/recipes/": "/docs/paas/eu/user-guide/", "/docs/user-guide/rule-engine-2-0/nodes/action/add-to-group/": "/docs/reference/rule-engine/nodes/action/add-to-group/", + "/docs/user-guide/rule-engine-2-0/nodes/action/assign-entity-group-to-edge/": "/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge/", "/docs/user-guide/rule-engine-2-0/nodes/action/assign-to-customer/": "/docs/reference/rule-engine/nodes/action/assign-to-customer/", "/docs/user-guide/rule-engine-2-0/nodes/action/calculated-fields/": "/docs/reference/rule-engine/nodes/action/calculated-fields/", "/docs/user-guide/rule-engine-2-0/nodes/action/change-owner/": "/docs/reference/rule-engine/nodes/action/change-owner/", @@ -1297,6 +1298,7 @@ "/docs/user-guide/rule-engine-2-0/nodes/action/save-attributes/": "/docs/reference/rule-engine/nodes/action/save-attributes/", "/docs/user-guide/rule-engine-2-0/nodes/action/save-timeseries/": "/docs/reference/rule-engine/nodes/action/save-timeseries/", "/docs/user-guide/rule-engine-2-0/nodes/action/save-to-custom-table/": "/docs/reference/rule-engine/nodes/action/save-to-custom-table/", + "/docs/user-guide/rule-engine-2-0/nodes/action/unassign-entity-group-from-edge/": "/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge/", "/docs/user-guide/rule-engine-2-0/nodes/action/unassign-from-customer/": "/docs/reference/rule-engine/nodes/action/unassign-from-customer/", "/docs/user-guide/rule-engine-2-0/nodes/analytics/aggregate-latest/": "/docs/reference/rule-engine/nodes/analytics/aggregate-latest/", "/docs/user-guide/rule-engine-2-0/nodes/analytics/aggregate-stream/": "/docs/reference/rule-engine/nodes/analytics/aggregate-stream/", @@ -1363,6 +1365,7 @@ "/docs/user-guide/rule-engine-2-0/nodes/transformation/split-array-msg/": "/docs/reference/rule-engine/nodes/transformation/split-array-msg/", "/docs/user-guide/rule-engine-2-0/nodes/transformation/to-email/": "/docs/reference/rule-engine/nodes/transformation/to-email/", "/docs/pe/user-guide/rule-engine-2-0/nodes/action/add-to-group/": "/docs/pe/reference/rule-engine/nodes/action/add-to-group/", + "/docs/pe/user-guide/rule-engine-2-0/nodes/action/assign-entity-group-to-edge/": "/docs/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge/", "/docs/pe/user-guide/rule-engine-2-0/nodes/action/assign-to-customer/": "/docs/pe/reference/rule-engine/nodes/action/assign-to-customer/", "/docs/pe/user-guide/rule-engine-2-0/nodes/action/calculated-fields/": "/docs/pe/reference/rule-engine/nodes/action/calculated-fields/", "/docs/pe/user-guide/rule-engine-2-0/nodes/action/change-owner/": "/docs/pe/reference/rule-engine/nodes/action/change-owner/", @@ -1393,6 +1396,7 @@ "/docs/pe/user-guide/rule-engine-2-0/nodes/action/save-attributes/": "/docs/pe/reference/rule-engine/nodes/action/save-attributes/", "/docs/pe/user-guide/rule-engine-2-0/nodes/action/save-timeseries/": "/docs/pe/reference/rule-engine/nodes/action/save-timeseries/", "/docs/pe/user-guide/rule-engine-2-0/nodes/action/save-to-custom-table/": "/docs/pe/reference/rule-engine/nodes/action/save-to-custom-table/", + "/docs/pe/user-guide/rule-engine-2-0/nodes/action/unassign-entity-group-from-edge/": "/docs/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge/", "/docs/pe/user-guide/rule-engine-2-0/nodes/action/unassign-from-customer/": "/docs/pe/reference/rule-engine/nodes/action/unassign-from-customer/", "/docs/pe/user-guide/rule-engine-2-0/nodes/analytics/aggregate-latest/": "/docs/pe/reference/rule-engine/nodes/analytics/aggregate-latest/", "/docs/pe/user-guide/rule-engine-2-0/nodes/analytics/aggregate-stream/": "/docs/pe/reference/rule-engine/nodes/analytics/aggregate-stream/", @@ -1459,6 +1463,7 @@ "/docs/pe/user-guide/rule-engine-2-0/nodes/transformation/split-array-msg/": "/docs/pe/reference/rule-engine/nodes/transformation/split-array-msg/", "/docs/pe/user-guide/rule-engine-2-0/nodes/transformation/to-email/": "/docs/pe/reference/rule-engine/nodes/transformation/to-email/", "/docs/paas/user-guide/rule-engine-2-0/nodes/action/add-to-group/": "/docs/paas/reference/rule-engine/nodes/action/add-to-group/", + "/docs/paas/user-guide/rule-engine-2-0/nodes/action/assign-entity-group-to-edge/": "/docs/paas/reference/rule-engine/nodes/action/assign-entity-group-to-edge/", "/docs/paas/user-guide/rule-engine-2-0/nodes/action/assign-to-customer/": "/docs/paas/reference/rule-engine/nodes/action/assign-to-customer/", "/docs/paas/user-guide/rule-engine-2-0/nodes/action/calculated-fields/": "/docs/paas/reference/rule-engine/nodes/action/calculated-fields/", "/docs/paas/user-guide/rule-engine-2-0/nodes/action/change-owner/": "/docs/paas/reference/rule-engine/nodes/action/change-owner/", @@ -1489,6 +1494,7 @@ "/docs/paas/user-guide/rule-engine-2-0/nodes/action/save-attributes/": "/docs/paas/reference/rule-engine/nodes/action/save-attributes/", "/docs/paas/user-guide/rule-engine-2-0/nodes/action/save-timeseries/": "/docs/paas/reference/rule-engine/nodes/action/save-timeseries/", "/docs/paas/user-guide/rule-engine-2-0/nodes/action/save-to-custom-table/": "/docs/paas/reference/rule-engine/nodes/action/save-to-custom-table/", + "/docs/paas/user-guide/rule-engine-2-0/nodes/action/unassign-entity-group-from-edge/": "/docs/paas/reference/rule-engine/nodes/action/unassign-entity-group-from-edge/", "/docs/paas/user-guide/rule-engine-2-0/nodes/action/unassign-from-customer/": "/docs/paas/reference/rule-engine/nodes/action/unassign-from-customer/", "/docs/paas/user-guide/rule-engine-2-0/nodes/analytics/aggregate-latest/": "/docs/paas/reference/rule-engine/nodes/analytics/aggregate-latest/", "/docs/paas/user-guide/rule-engine-2-0/nodes/analytics/aggregate-stream/": "/docs/paas/reference/rule-engine/nodes/analytics/aggregate-stream/", @@ -1555,6 +1561,7 @@ "/docs/paas/user-guide/rule-engine-2-0/nodes/transformation/split-array-msg/": "/docs/paas/reference/rule-engine/nodes/transformation/split-array-msg/", "/docs/paas/user-guide/rule-engine-2-0/nodes/transformation/to-email/": "/docs/paas/reference/rule-engine/nodes/transformation/to-email/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/add-to-group/": "/docs/paas/eu/reference/rule-engine/nodes/action/add-to-group/", + "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/assign-entity-group-to-edge/": "/docs/paas/eu/reference/rule-engine/nodes/action/assign-entity-group-to-edge/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/assign-to-customer/": "/docs/paas/eu/reference/rule-engine/nodes/action/assign-to-customer/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/calculated-fields/": "/docs/paas/eu/reference/rule-engine/nodes/action/calculated-fields/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/change-owner/": "/docs/paas/eu/reference/rule-engine/nodes/action/change-owner/", @@ -1585,6 +1592,7 @@ "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/save-attributes/": "/docs/paas/eu/reference/rule-engine/nodes/action/save-attributes/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/save-timeseries/": "/docs/paas/eu/reference/rule-engine/nodes/action/save-timeseries/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/save-to-custom-table/": "/docs/paas/eu/reference/rule-engine/nodes/action/save-to-custom-table/", + "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/unassign-entity-group-from-edge/": "/docs/paas/eu/reference/rule-engine/nodes/action/unassign-entity-group-from-edge/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/action/unassign-from-customer/": "/docs/paas/eu/reference/rule-engine/nodes/action/unassign-from-customer/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/analytics/aggregate-latest/": "/docs/paas/eu/reference/rule-engine/nodes/analytics/aggregate-latest/", "/docs/paas/eu/user-guide/rule-engine-2-0/nodes/analytics/aggregate-stream/": "/docs/paas/eu/reference/rule-engine/nodes/analytics/aggregate-stream/", @@ -1835,6 +1843,7 @@ "/docs/pe/edge/reference/rest-api/": "/docs/edge/pe/reference/rest-api/", "/docs/pe/edge/reference/rule-engine/message-types/": "/docs/edge/pe/reference/rule-engine/message-types/", "/docs/pe/edge/reference/rule-engine/nodes/action/add-to-group/": "/docs/edge/pe/reference/rule-engine/nodes/action/add-to-group/", + "/docs/pe/edge/reference/rule-engine/nodes/action/assign-entity-group-to-edge/": "/docs/edge/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge/", "/docs/pe/edge/reference/rule-engine/nodes/action/assign-to-customer/": "/docs/edge/pe/reference/rule-engine/nodes/action/assign-to-customer/", "/docs/pe/edge/reference/rule-engine/nodes/action/calculated-fields/": "/docs/edge/pe/reference/rule-engine/nodes/action/calculated-fields/", "/docs/pe/edge/reference/rule-engine/nodes/action/change-owner/": "/docs/edge/pe/reference/rule-engine/nodes/action/change-owner/", @@ -1865,6 +1874,7 @@ "/docs/pe/edge/reference/rule-engine/nodes/action/save-attributes/": "/docs/edge/pe/reference/rule-engine/nodes/action/save-attributes/", "/docs/pe/edge/reference/rule-engine/nodes/action/save-timeseries/": "/docs/edge/pe/reference/rule-engine/nodes/action/save-timeseries/", "/docs/pe/edge/reference/rule-engine/nodes/action/save-to-custom-table/": "/docs/edge/pe/reference/rule-engine/nodes/action/save-to-custom-table/", + "/docs/pe/edge/reference/rule-engine/nodes/action/unassign-entity-group-from-edge/": "/docs/edge/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge/", "/docs/pe/edge/reference/rule-engine/nodes/action/unassign-from-customer/": "/docs/edge/pe/reference/rule-engine/nodes/action/unassign-from-customer/", "/docs/pe/edge/reference/rule-engine/nodes/analytics/aggregate-latest/": "/docs/edge/pe/reference/rule-engine/nodes/analytics/aggregate-latest/", "/docs/pe/edge/reference/rule-engine/nodes/analytics/aggregate-stream/": "/docs/edge/pe/reference/rule-engine/nodes/analytics/aggregate-stream/", diff --git a/src/content/_includes/docs/reference/rule-engine/nodes/action.mdx b/src/content/_includes/docs/reference/rule-engine/nodes/action.mdx index 24aeb53331..d7b9d53654 100644 --- a/src/content/_includes/docs/reference/rule-engine/nodes/action.mdx +++ b/src/content/_includes/docs/reference/rule-engine/nodes/action.mdx @@ -32,9 +32,11 @@ system state. | Unassign from customer | Removes the originator entity from its current customer assignment | | Push to cloud | Forwards the message from a ThingsBoard Edge instance to the cloud ThingsBoard instance | | Add to group | Adds the originator to an entity group found by name pattern | +| Assign entity group to edge | Assigns configured entity groups to an edge, resolving the edge from the originator or by name pattern | | Change owner | Changes the ownership of the originator to a specified tenant or customer | | Generate dashboard report | Captures a screenshot of a configured dashboard via a headless browser and saves it as a blob entity | | Generate report | Generates a report from a template and optionally notifies configured recipients | | Integration downlink | Pushes the message as a downlink to a selected integration | | Remove from group | Removes the originator from an entity group found by name pattern | | Save to custom table | Persists message data to a custom Cassandra table using a configurable field mapping | +| Unassign entity group from edge | Removes configured entity groups from an edge, resolving the edge from the originator or by name pattern | diff --git a/src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx new file mode 100644 index 0000000000..c28d8d0116 --- /dev/null +++ b/src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -0,0 +1,153 @@ +import DocLink from '@components/DocLink.astro'; +import { Aside } from '@astrojs/starlight/components'; + + + +Use this node on a cloud instance to assign entity groups to an edge from a rule chain — for example, provisioning a newly created edge with its `Site Devices` and `Site Dashboards` groups as soon as it reports for the first time. An entity group is the only way devices, assets, entity views, dashboards, and users reach an edge, so this node is what turns edge onboarding into an automated flow instead of a manual assignment. Group type and group name both support templatization. + + + +## Configuration + +- **Edge** — required. How the target edge is resolved: + - **Message originator** — the originator must be an `EDGE` entity. Any other originator type routes via `Failure`. + - **Edge name pattern** — resolves the edge by name within the tenant. Required when this option is selected. Supports templatization, so the edge can be named by the message itself. +- **Entity groups** — required, at least one row. Each row is a group type and a group name: + - **Group type** — one of `Device`, `Asset`, `Entity View`, `Dashboard`, `User`. These are the only group types an edge can synchronise. + - **Group name** — name of the group to assign. Matching is case-sensitive. + - Both fields support templatization, so one node can serve every group type present in a provisioning payload. +- **Create new group if not exists** — when enabled, a group that is not found anywhere in the ownership hierarchy is created under the edge's owner. When disabled, a group that cannot be found routes via `Failure`. + + + +## Message processing algorithm + +1. Resolve the target edge, either from the message originator or from the edge name pattern. +2. For each configured row, resolve the group type and the group name from message data and metadata. +3. Look the group up by type and name, starting at the edge's owner and walking up the ownership hierarchy to the tenant. A group owned above the edge's owner is reused rather than duplicated. +4. If the group is not found and **Create new group if not exists** is enabled, create it under the edge's owner — the narrowest scope the edge can see. +5. Deduplicate the resolved groups by id, so two patterns that resolve to the same group produce a single assignment. +6. Check each resolved group against the edge. Groups that are already assigned are skipped. +7. Assign the remaining groups in configured row order. +8. Route the unchanged message via `Success`. + +Every row is resolved before anything is assigned, so a misconfigured row is caught before the first write. + +Skipping already-assigned groups is not only an optimisation: a redundant assignment re-publishes the `ASSIGNED_TO_EDGE` event, which makes the edge request every entity in the group again. + +## Output connections + +| Connection | Condition | +|------------|-----------| +| `Success` | Every configured group is assigned to the edge, or was already assigned. | +| `Failure` | Originator is not an `EDGE` entity, the edge was not found, a pattern resolved to an empty or unsupported value, a group was not found while creation is disabled, a reserved group name was used, or an unexpected error. | + +## Examples + +### Example 1 — Assign a device group to the originating edge + +**Originator**: an `EDGE` entity. + +```json maxLines=20 collapsible +{ + "edgeSource": "MESSAGE_ORIGINATOR", + "edgeNamePattern": null, + "entityGroups": [ + { "groupType": "DEVICE", "groupName": "Site Devices" } + ], + "createGroupIfNotExists": false +} +``` + +**State**: `Site Devices` exists under the tenant and is not yet assigned. **Result**: the group is assigned to the originating edge; the edge starts syncing its devices. + +--- + +### Example 2 — Assign several group types at once + +```json maxLines=20 collapsible +{ + "edgeSource": "MESSAGE_ORIGINATOR", + "edgeNamePattern": null, + "entityGroups": [ + { "groupType": "DEVICE", "groupName": "Site Devices" }, + { "groupType": "DASHBOARD", "groupName": "Site Dashboards" }, + { "groupType": "USER", "groupName": "Site Operators" } + ], + "createGroupIfNotExists": false +} +``` + +**Result**: all three groups are assigned, in the order listed. + +--- + +### Example 3 — Resolve the edge and the group from the message + +**Data**: `{ "edgeName": "Warehouse edge", "siteCode": "WH-14" }` + +```json maxLines=20 collapsible +{ + "edgeSource": "EDGE_NAME_PATTERN", + "edgeNamePattern": "$[edgeName]", + "entityGroups": [ + { "groupType": "DEVICE", "groupName": "$[siteCode] devices" } + ], + "createGroupIfNotExists": false +} +``` + +**Result**: the edge `Warehouse edge` is resolved by name, and the group `WH-14 devices` is assigned to it. The originator is ignored on this path, so the message can come from any entity. + +--- + +### Example 4 — Provision a group that does not exist yet + +```json maxLines=20 collapsible +{ + "edgeSource": "MESSAGE_ORIGINATOR", + "edgeNamePattern": null, + "entityGroups": [ + { "groupType": "DEVICE", "groupName": "Provisioned Devices" } + ], + "createGroupIfNotExists": true +} +``` + +**State**: no `Provisioned Devices` device group exists in the edge's ownership hierarchy. **Result**: the group is created under the edge's owner and assigned to the edge. + +## JSON schema + +```json maxLines=25 collapsible +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "TbAssignEntityGroupToEdgeNodeConfiguration", + "type": "object", + "required": ["edgeSource", "entityGroups", "createGroupIfNotExists"], + "additionalProperties": false, + "properties": { + "edgeSource": { "enum": ["MESSAGE_ORIGINATOR", "EDGE_NAME_PATTERN"] }, + "edgeNamePattern": { "type": ["string", "null"] }, + "entityGroups": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["groupType", "groupName"], + "additionalProperties": false, + "properties": { + "groupType": { "type": "string" }, + "groupName": { "type": "string" } + } + } + }, + "createGroupIfNotExists": { "type": "boolean" } + } +} +``` diff --git a/src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx new file mode 100644 index 0000000000..54e030ab7e --- /dev/null +++ b/src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -0,0 +1,129 @@ +import DocLink from '@components/DocLink.astro'; +import { Aside } from '@astrojs/starlight/components'; + + + +Use this node on a cloud instance to remove entity groups from an edge from a rule chain — for example, revoking a site's dashboards and operators when the site is decommissioned, or narrowing what an edge receives after a change of ownership. Group type and group name both support templatization. + + + +## Configuration + +- **Edge** — required. How the target edge is resolved: + - **Message originator** — the originator must be an `EDGE` entity. Any other originator type routes via `Failure`. + - **Edge name pattern** — resolves the edge by name within the tenant. Required when this option is selected. Supports templatization, so the edge can be named by the message itself. +- **Entity groups** — required, at least one row. Each row is a group type and a group name: + - **Group type** — one of `Device`, `Asset`, `Entity View`, `Dashboard`, `User`. These are the only group types an edge can synchronise. + - **Group name** — name of the group to unassign. Matching is case-sensitive. + - Both fields support templatization. + +This node never creates entity groups. A group that cannot be resolved routes via `Failure`, since that is indistinguishable from a misconfigured name. + + + +## Message processing algorithm + +1. Resolve the target edge, either from the message originator or from the edge name pattern. +2. For each configured row, resolve the group type and the group name from message data and metadata. +3. Look the group up by type and name, starting at the edge's owner and walking up the ownership hierarchy to the tenant. +4. Deduplicate the resolved groups by id, so two patterns that resolve to the same group produce a single unassignment. +5. Check each resolved group against the edge. Groups that are not currently assigned are skipped. +6. Unassign the remaining groups in configured row order. +7. Route the unchanged message via `Success`. + +Every row is resolved before anything is unassigned, so a misconfigured row is caught before the first write. + +## Output connections + +| Connection | Condition | +|------------|-----------| +| `Success` | Every configured group is unassigned from the edge, or was not assigned to begin with. | +| `Failure` | Originator is not an `EDGE` entity, the edge was not found, a pattern resolved to an empty or unsupported value, a group was not found, a reserved group name was used, or an unexpected error. | + +## Examples + +### Example 1 — Unassign a device group from the originating edge + +**Originator**: an `EDGE` entity. + +```json maxLines=20 collapsible +{ + "edgeSource": "MESSAGE_ORIGINATOR", + "edgeNamePattern": null, + "entityGroups": [ + { "groupType": "DEVICE", "groupName": "Site Devices" } + ] +} +``` + +**State**: `Site Devices` is currently assigned to the edge. **Result**: the group is unassigned; the edge removes the group and its devices locally. + +--- + +### Example 2 — Decommission a site across group types + +```json maxLines=20 collapsible +{ + "edgeSource": "EDGE_NAME_PATTERN", + "edgeNamePattern": "${siteEdge}", + "entityGroups": [ + { "groupType": "DASHBOARD", "groupName": "Site Dashboards" }, + { "groupType": "USER", "groupName": "Site Operators" } + ] +} +``` + +**Metadata**: `{ "siteEdge": "Warehouse edge" }` + +**Result**: both groups are unassigned from `Warehouse edge`, in the order listed. + +--- + +### Example 3 — Group already unassigned + +```json maxLines=20 collapsible +{ + "edgeSource": "MESSAGE_ORIGINATOR", + "edgeNamePattern": null, + "entityGroups": [ + { "groupType": "DEVICE", "groupName": "Site Devices" } + ] +} +``` + +**State**: `Site Devices` exists but is not assigned to the edge. **Result**: nothing is written, no edge event is produced, and the message is routed via `Success`. Re-running the same chain is safe. + +## JSON schema + +```json maxLines=25 collapsible +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "TbUnassignEntityGroupFromEdgeNodeConfiguration", + "type": "object", + "required": ["edgeSource", "entityGroups"], + "additionalProperties": false, + "properties": { + "edgeSource": { "enum": ["MESSAGE_ORIGINATOR", "EDGE_NAME_PATTERN"] }, + "edgeNamePattern": { "type": ["string", "null"] }, + "entityGroups": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["groupType", "groupName"], + "additionalProperties": false, + "properties": { + "groupType": { "type": "string" }, + "groupName": { "type": "string" } + } + } + } + } +} +``` diff --git a/src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx new file mode 100644 index 0000000000..e1af81aa03 --- /dev/null +++ b/src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Assign Entity Group to Edge +description: Discover the Assign Entity Group to Edge action node in ThingsBoard Rule Engine. Automate edge provisioning by assigning device, asset, dashboard, and user groups to an edge from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx new file mode 100644 index 0000000000..c936e81a7e --- /dev/null +++ b/src/content/docs/docs/edge/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Unassign Entity Group from Edge +description: Discover the Unassign Entity Group from Edge action node in ThingsBoard Rule Engine. Revoke device, asset, dashboard, and user groups from an edge automatically from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/edge/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/docs/docs/edge/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx new file mode 100644 index 0000000000..5f1b53f06c --- /dev/null +++ b/src/content/docs/docs/edge/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Assign Entity Group to Edge +description: Discover the Assign Entity Group to Edge action node in ThingsBoard Rule Engine. Automate edge provisioning by assigning device, asset, dashboard, and user groups to an edge from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/edge/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/docs/docs/edge/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx new file mode 100644 index 0000000000..6273502da5 --- /dev/null +++ b/src/content/docs/docs/edge/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Unassign Entity Group from Edge +description: Discover the Unassign Entity Group from Edge action node in ThingsBoard Rule Engine. Revoke device, asset, dashboard, and user groups from an edge automatically from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx new file mode 100644 index 0000000000..8ed2f2766b --- /dev/null +++ b/src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Assign Entity Group to Edge +description: Discover the Assign Entity Group to Edge action node in ThingsBoard Rule Engine. Automate edge provisioning by assigning device, asset, dashboard, and user groups to an edge from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx new file mode 100644 index 0000000000..f022992e6f --- /dev/null +++ b/src/content/docs/docs/paas/eu/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Unassign Entity Group from Edge +description: Discover the Unassign Entity Group from Edge action node in ThingsBoard Rule Engine. Revoke device, asset, dashboard, and user groups from an edge automatically from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/paas/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/docs/docs/paas/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx new file mode 100644 index 0000000000..c4b3ed9908 --- /dev/null +++ b/src/content/docs/docs/paas/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Assign Entity Group to Edge +description: Discover the Assign Entity Group to Edge action node in ThingsBoard Rule Engine. Automate edge provisioning by assigning device, asset, dashboard, and user groups to an edge from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/paas/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/docs/docs/paas/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx new file mode 100644 index 0000000000..3d050ea9af --- /dev/null +++ b/src/content/docs/docs/paas/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Unassign Entity Group from Edge +description: Discover the Unassign Entity Group from Edge action node in ThingsBoard Rule Engine. Revoke device, asset, dashboard, and user groups from an edge automatically from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/docs/docs/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx new file mode 100644 index 0000000000..ec8b87a75f --- /dev/null +++ b/src/content/docs/docs/pe/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Assign Entity Group to Edge +description: Discover the Assign Entity Group to Edge action node in ThingsBoard Rule Engine. Automate edge provisioning by assigning device, asset, dashboard, and user groups to an edge from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/docs/docs/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx new file mode 100644 index 0000000000..174dbd81e4 --- /dev/null +++ b/src/content/docs/docs/pe/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Unassign Entity Group from Edge +description: Discover the Unassign Entity Group from Edge action node in ThingsBoard Rule Engine. Revoke device, asset, dashboard, and user groups from an edge automatically from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/docs/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx new file mode 100644 index 0000000000..d471bb8759 --- /dev/null +++ b/src/content/docs/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Assign Entity Group to Edge +description: Discover the Assign Entity Group to Edge action node in ThingsBoard Rule Engine. Automate edge provisioning by assigning device, asset, dashboard, and user groups to an edge from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx' +import { Products } from '~/models/site.models' + + diff --git a/src/content/docs/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/docs/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx new file mode 100644 index 0000000000..81b9b6f19f --- /dev/null +++ b/src/content/docs/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -0,0 +1,8 @@ +--- +title: Unassign Entity Group from Edge +description: Discover the Unassign Entity Group from Edge action node in ThingsBoard Rule Engine. Revoke device, asset, dashboard, and user groups from an edge automatically from a rule chain. +--- +import NodeComponent from '@includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx' +import { Products } from '~/models/site.models' + + From 5f8113483c1f621ba6b8142de2a14ccbafcb3770 Mon Sep 17 00:00:00 2001 From: Andrii Landiak Date: Thu, 27 Aug 2026 12:17:05 +0300 Subject: [PATCH 2/2] Document rule chain wiring for edge entity group nodes --- .../action/assign-entity-group-to-edge.mdx | 24 +++++++++++++++++++ .../unassign-entity-group-from-edge.mdx | 6 +++++ 2 files changed, 30 insertions(+) diff --git a/src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx b/src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx index c28d8d0116..6b1013b657 100644 --- a/src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx +++ b/src/content/_includes/docs/reference/rule-engine/nodes/action/assign-entity-group-to-edge.mdx @@ -26,6 +26,30 @@ Use this node on a cloud instance to assign entity groups to an edge from a rule The platform-managed `All` and `[Edge] … All` groups cannot be assigned. They are rejected when the node is saved, and again at runtime if a pattern resolves to one. +## Usage + +**Message originator** suits chains where the message is already about the edge — an edge lifecycle event, or an attribute update on the edge itself. The originator must be an `EDGE` entity; any other originator type routes via `Failure`. + +**Edge name pattern** suits chains where the message comes from somewhere else and names the edge it targets. That mode needs the edge name to be present in the message by the time this node runs, and there are three usual ways to arrange that: + +1. **The payload already carries it.** A provisioning request submitted through `POST /api/rule-engine/` with a body such as `{ "edgeName": "WH-14 edge" }` needs nothing extra — set the pattern to `$[edgeName]`. This is the most direct use of the mode. +2. **The edge name is stored as an attribute.** Put an originator attributes node ahead of this one to copy a server attribute such as `assignedEdge` into metadata, then use `${assignedEdge}`. Related entity data does the same job when the name lives on a related asset rather than the originator. +3. **The edge name has to be derived.** Only this case genuinely needs a script node — compute the name into metadata and let this node read it. + +### Guarding the node + +A pattern that fails to resolve routes via `Failure` rather than being skipped: a missing metadata key looks exactly like a typo in the key name, so the node reports it instead of ignoring the message. Put a check fields presence node ahead of it, configured with the message field or metadata key the pattern reads, so only messages that can be acted on ever arrive. That is configuration only — no script required. + +**Connect the `Failure` output.** An unconnected `Failure` drops the message, which turns a mistyped edge name into silence. Route it to a log node or raise an alarm so bad provisioning data stays visible. + +### Handling both modes in one chain + +When a single chain receives both edge-originated messages and messages that name an edge, put an entity type switch node in front and use two instances of this node: send the `Edge` branch to an instance configured with **Message originator**, and the remaining branches to an instance configured with **Edge name pattern**. + +### Message rate + +Every message that reaches the node resolves its configured rows and checks each resolved group against the edge, whether or not anything changes. Groups already assigned are skipped, so re-running a chain is harmless — but the lookups still happen on every message. Keep this node on a provisioning or lifecycle path rather than on raw telemetry, and place a filter ahead of it when the chain carries high-rate traffic. + ## Message processing algorithm 1. Resolve the target edge, either from the message originator or from the edge name pattern. diff --git a/src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx b/src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx index 54e030ab7e..45d4900538 100644 --- a/src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx +++ b/src/content/_includes/docs/reference/rule-engine/nodes/action/unassign-entity-group-from-edge.mdx @@ -27,6 +27,12 @@ This node never creates entity groups. A group that cannot be resolved routes vi The platform-managed `All` and `[Edge] … All` groups cannot be unassigned. They are rejected when the node is saved, and again at runtime if a pattern resolves to one. +## Usage + +The edge resolution modes, the guarding patterns, and the message-rate considerations are the same as for assign entity group to edge. + +One difference matters when wiring this node: unassigning is destructive on the edge side, so a pattern that resolves to an unintended group name removes real data from that edge's local database. Guard the node with a check fields presence node, connect the `Failure` output, and prefer literal group names over patterns unless the chain genuinely needs them. + ## Message processing algorithm 1. Resolve the target edge, either from the message originator or from the edge name pattern.