Skip to content

Platform

Products

Define a product once, with its properties, buckets, flows, API resources, script and dashboard, and apply it to a whole fleet of devices.

Feature5 min read

A product is the template of a fleet of devices of the same model. You configure its profile once, and every device assigned to it gets the same properties, Data Buckets, flows, device resources, dashboard and services, whether it connects over IOTMP, MQTT or HTTP.

When to use it ​

  • To manage many devices of the same model without configuring each one.
  • To turn the MQTT topics or HTTP requests of a device into properties, stored data and device resources.
  • To compute values on the platform with JavaScript, for example for virtual devices.
  • To create devices automatically when they first connect.

Create a product ​

YOUR_SERVER is iot.thinger.io on the free Cloud account, or the domain of your private instance.

Console

  1. Open Products

    Go to Products and click Add Product (or Create a new Product if you have none yet).

  2. Fill in the form

    Set the Product ID, the Product Name and an optional Product Description, and leave Enabled on.

    Add Product form with the product ID, name and description filled in
    Add a product
  3. Save it

    Click Add Product. The product opens on its Profile tab, where you configure what it does.

API

POST/v1/users/{user}/productsAPI reference
bash
curl -X POST "https://YOUR_SERVER/v1/users/YOUR_USER/products" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product": "meter", "name": "Meter", "description": "Energy meters", "enabled": true}'

YOUR_TOKEN is an access token with permission to create products. The body can also carry the whole profile.

CLI

bash
thinger product create meter -n "Meter" -d "Energy meters"

Add --from product.json to create it from a JSON document with its config and profile. See the CLI reference.

AI

Ask your AI agent

Create a product called meter for my energy meters.

The agent uses thinger_resource_create with the product type. See MCP tools.

Assign devices to a product ​

A device follows the profile of its product as soon as you assign it. Each device can belong to one product.

Console

Open the device, go to Settings, and under Advanced Options choose the Product. Click Update Device. You can also choose the product when you add the device.

API

PUT/v1/users/{user}/devices/{device}API reference
bash
curl -X PUT "https://YOUR_SERVER/v1/users/YOUR_USER/devices/YOUR_DEVICE" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"product": "meter"}'

CLI

bash
thinger device set-product YOUR_DEVICE meter

Pass "" as the product to unassign the device, or use -p meter in thinger device create.

AI

Ask your AI agent

Assign the devices meter_001 to meter_010 to the product meter.

The product profile ​

The Profile tab holds what the product does for each of its devices, in one card per part. Each entry of a card can be enabled or disabled on its own, and only runs while the product is enabled.

The product also has its own tabs for what its devices show and expose:

The Properties tab holds the properties of the product itself, which every device inherits (see Product properties). The menu of the product also has Inspector (the live events of the product), Profile Graph (a graph of what feeds each entry and where its data goes), Plugin Exporter (package the product as a plugin) and Settings, where Product Icon and Product Fields set how its devices look on asset maps and tables.

Profile tab of the meter product with its Properties, Buckets, Flows, API Resources, Auto Provision and Product Script cards
Profile tab of a product
SOURCESPRODUCT PROFILETARGETSASSIGNED DEVICESEACH DEVICE SHOWSDevice Resourceread every intervalDevice Streamstreamed by the deviceDevice Topicdevices/{{device}}/…Device Eventdevice_state_changeProduct Streamfrom flows, API resourcesPropertieskeep valuesBucketsstore historyFlowsroute dataAPI Resourcesdevice resources on callAuto Provisioncreates matching devicesProduct ScriptJavaScript functions that the cards call forPayload Processing, Product Function and resolversDevice propertyData BucketMQTT topicEndpointPlugin endpointProduct streamwritestorepublishcallsendpublishapplied to each deviceIOTMP devicemeter_01MQTT devicemeter_02HTTP devicemeter_03Product dashboardits Dashboard tab, its dataServicesIOTMP web UIs, desktops
Product profile at a glance

Sources, targets and payloads ​

Properties, buckets and flows take their data from a source; flows and API resources send data to a target. The console offers the same choices in every card:

SourcesourceData
Device ResourceresourceThe platform reads a device resource every Sampling Interval, or the device streams it (Stream by Device).
Device Streamresource_streamA device resource that the device streams on its own.
Device TopictopicMessages on an MQTT topic, such as devices/{{device}}/telemetry. See Topics.
Device EventeventA platform event of the device, such as device_state_change.
Product Streamproduct_streamA stream published by a flow or API resource of a product. See Flows.
SOURCEPAYLOADPAYLOAD PROCESSINGTARGETDevice ResourceDevice StreamDevice TopicDevice EventProduct StreamSource Payloadthe data as receivedSource Eventthe whole eventTemplate PayloadJSON with placeholdersNoneno dataPayload Processingoptionalfunction fix(p) {p.t = p.t / 10;return p;}a product script functionan empty result skips itDevice ResourceDevice StreamDevice TopicDevice PropertyProduct FunctionEndpoint CallPlugin EndpointProduct Streamwithout Payload Processing, straight to the targetTemplate placeholdersreplaced for each device when the payload is built{{payload.x}}{{device}}{{user}}{{product}}{{property.x}}{{api.x}}{{meta.x}}{{x:function}}a field of the data; {{payload}} is all of itthe device IDthe username of the accountthe product IDa property of the devicethe result of another API resourcea field of the device record, such as namethe value, passed through a script function
Payload pipeline

Topics ​

A Device Topic source or target uses the topics of the devices of the product. In a topic, {{device}} and any other {{name}} match one level, and the MQTT wildcards work too: + matches one level and # the rest of the topic. Both of these receive the temperature of every device, as long as each device publishes under its own ID:

text
my_product/{{device}}/temperature
my_product/+/temperature

{{name=a|b}} matches only the listed values: product buckets use it to store several topics in one record (see Tags and fields from the topic).

Payloads ​

Each source or target builds a Payload: Source Payload (the data as received), Source Event (the whole event), Template Payload (a JSON template) or None. Payload Processing passes it through a function of the product script.

With Source Event, the payload is the event that carried the data. A message on a topic arrives as a device_topic_publish event:

json
{
  "event": "device_topic_publish",
  "user": "YOUR_USER",
  "device": "plug_01",
  "product": "shelly_plug_s",
  "asset_type": "",
  "asset_group": "",
  "topic": "shellies/plug_01/relay/0/power",
  "payload": 6.55,
  "qos": 0,
  "dup": 0,
  "retain": 0,
  "ts": 1760702400000
}

A device resource arrives as a device_resource_stream event, with resource instead of topic, qos, dup and retain. ts is the time in milliseconds.

Templates use these placeholders:

PlaceholderValue
{{payload}}, {{payload.<field>}}The incoming data, or one of its fields.
{{device}}, {{user}}, {{product}}The device ID, the account and the product ID.
{{<field>}}Any other field of the event, such as {{topic}}, {{asset_type}}, {{asset_group}} or {{ts}}. In the request of an API resource, {{resource}} is the name of the API resource.
{{property.<id>}}, {{property.<id>.<field>}}A property of the device, inherited ones included, or one of its fields.
{{api.<resource>}}, {{api.<resource>.<field>}}The result of another API resource of the product.
{{meta.<field>}}A field of the device record, such as name.
{{<placeholder>:<function>}}The placeholder passed through a function of the product script.

A placeholder writes its value as is: a number or a JSON object as JSON, a text without quotes. Put quotes around the placeholders that hold text. This template stores two fields of the payload under new names:

json
{"update": {{payload.new_fw}}, "ip": "{{payload.ip}}"}

If the result is not valid JSON, the target receives it as plain text. In the request of an API resource, {{payload=<default>}} and {{payload.<field>=<default>}} also set the input of the resource: see Default input. Anywhere else, the text after = is ignored.

Examples ​

Three products, step by step, with real devices:

Limits ​

  • The Product ID uses letters, numbers and underscores, and cannot change after you create the product.
  • A disabled product, or a disabled entry of its profile, does nothing for its devices.
  • Removing a product keeps its devices, without a product. The Data Buckets it created stay too.
  • Saving the profile from the API replaces a whole card (PUT .../profile/{category}) or one entry (PUT .../profile/{category}/{resource}): see the REST API reference.
  • The number of products depends on your plan: see Plans and limits.