Skip to main content

Device Groups

Base path: /cgg/groups — every route requires authentication, either an API key or a signed-in session.

A device group binds a set of devices to a project version and to shared settings and tables. Changing the group's firmware, variables or tables applies the change to every member device, and any device added later inherits the group's current configuration.

Groups follow the same access rules as devices: personal groups belong to their creator, workspace groups are reachable by workspace members, and workspace operators are read-only.

MethodPathPurpose
GET/cgg/groupsList groups
POST/cgg/groupsCreate a group
GET/cgg/groups/:idGet one group
PUT/cgg/groups/:idRename or re-target a group
DELETE/cgg/groups/:idDelete a group
POST/cgg/groups/:id/firmwarePush a firmware version to all members
POST/cgg/groups/:id/devicesAdd devices to the group
DELETE/cgg/groups/:id/devices/:deviceIdRemove a device from the group
POST/cgg/groups/:id/variablesSet shared settings on all members
POST/cgg/groups/:id/tablesSave a shared table on all members
DELETE/cgg/groups/:id/tables/:tableNameRemove a shared table from the group

The group object

{
"_id": "664a20fa8c9d0e00112233aa",
"name": "Floor 2 boilers",
"user": "8a3f…",
"workspace": "664a1f2b8c9d0e0011223344",
"tenant": "664a20338c9d0e0011223399",
"project": "664a1f2b8c9d0e0011223301",
"projectVersion": "664a1f9c8c9d0e0011223377",
"settings": [
{ "variable": "setpoint", "value": 21 }
],
"tables": [
{ "name": "schedule", "data": "hour,value\r\n8,21\r\n" }
],
"createdAt": "…",
"updatedAt": "…"
}

settings holds the delegated variable values, tables the delegated table contents. Group membership itself lives on the device (device.group), not in the group document.

List groups

GET /cgg/groups
Query parameterDescription
startOffset, default 0
countPage size, default 10
searchCase-insensitive match on group name
workspaceReturn groups of this workspace instead of personal groups
tenantRestrict to a tenant. With workspace and no tenant, only groups without a tenant are returned

Each returned group is augmented with a devices array containing the deviceIds of its member devices.

{
"count": 3,
"data": [
{ "_id": "664a20fa…", "name": "Floor 2 boilers", "devices": ["665f3c1e…", "665f3c22…"] }
]
}

Create a group

POST /cgg/groups
{
"name": "Floor 2 boilers",
"workspace": "664a1f2b8c9d0e0011223344",
"tenant": "664a20338c9d0e0011223399",
"project": "664a1f2b8c9d0e0011223301",
"version": "664a1f9c8c9d0e0011223377"
}

All fields except name are optional. Note that the request field is version while the stored field is projectVersion. Creating a group inside a tenant requires tenant admin rights or workspace admin rights; operators cannot create groups.

Get one group

GET /cgg/groups/:id

Returns the group with project and projectVersion populated as full documents.

Update a group

PUT /cgg/groups/:id
{
"name": "Floor 2 boilers",
"project": "664a1f2b8c9d0e0011223301",
"version": "664a1fd18c9d0e0011223388"
}

When both project and version are supplied, the group is re-targeted to the new project version and its delegated configuration is reconciled: each entry in settings and tables is compared against the new version's stg (settings) and tbl (tables) feature definitions, and entries that no longer exist or whose definition changed are dropped. The response is the raw Mongo update result.

Delete a group

DELETE /cgg/groups/:id

Clears the group reference on every member device, then deletes the group. The devices themselves are kept.

Add and remove devices

POST   /cgg/groups/:id/devices
DELETE /cgg/groups/:id/devices/:deviceId
{ "devices": ["665f3c1e9d1b4a0012a7c8d1", "665f3c229d1b4a0012a7c8d2"] }

devices contains device _ids. Each device is assigned to the group and immediately receives the group's current tables and settings — they are written to the device's changes and pushed over MQTT. Returns 200 with an empty body.

DELETE …/devices/:deviceId unsets the device's group field; the device keeps whatever values it already received.

Assign firmware to a group

POST /cgg/groups/:id/firmware
{ "versionId": "664a1f9c8c9d0e0011223377" }

Every device in the group is told to download the version's firmware URL, and each device's changes.firmware is updated. A single audit log entry of type firmware records the group, the version and all affected deviceIds.

Returns 400 if the project version does not exist.

Set shared settings

POST /cgg/groups/:id/variables
{
"variables": [
{ "variable": "setpoint", "value": 21 },
{ "variable": "mode", "value": "auto" }
]
}

Each entry is written to changes.variables.<variable> on all member devices and pushed over MQTT, and the list replaces the group's settings, so devices added later inherit the same values. One audit log entry of type group_setting is written per variable.

Shared tables

POST   /cgg/groups/:id/tables
DELETE /cgg/groups/:id/tables/:tableName
{
"name": "schedule",
"data": "hour,value\r\n8,21\r\n18,18\r\n",
"action": "import"
}

The table is stored in the group's tables array (added, or updated in place) and pushed to every member device. If the submitted data is identical to what the group already holds, the request is a no-op. action defaults to import for the audit log entry.

Returns 400 when the group document has no tables array at all.

DELETE …/tables/:tableName removes the table from the group so future members no longer receive it, and writes a tables audit entry with action remove. It does not delete the table from devices that already have it.