The device should delete all recipes and create new ones based on the recipe templates provided in the request.
Request Topic and Payload
Topic
things5-production/v1/devices/<device-id>/cmd/sync_recipe_templates_v2_req
Payload Representation
{
"cookbook_sync_log_id": "7dc14fd9-8438-4771-9b13-e98d1a9d8c6e",
"request_id": "UUID sent in the request",
"manifest_url":
"https://things5.s3.eu-west-1.amazonaws.com/cookbook-syncs/2729d40a-8e33-4ec6-aa8c-b1050c3f19a6/manifest.json?X-Amz-Algorithm=...&X-Amz-Signature=...",
"expires_at": 1779711048527
}
Payload Parameters
| name | description | example |
|---|---|---|
| cookbook_sync_log_id | this id should be sent back with the response | |
| request_id | the request id to be sent back by the device when sending the response | |
| manifest_url | pre-signed HTTPS URL to download the manifest (see below) | |
| expires_at | Unix epoch in milliseconds after which manifest_url is no longer valid | 1779711048527 |
The device must download the manifest from
manifest_urlbeforeexpires_at, then download each recipe it needs.
Manifest
The device downloads the manifest from the manifest_url it received over MQTT. It lists every recipe in the cookbook.
Representation
{
"manifest_version": 1,
"cookbook_sync_id": "2729d40a-8e33-4ec6-aa8c-b1050c3f19a6",
"recipes": [
{
"index": 1,
"id": "a43c7763-3b95-4707-9fac-86b48348f00c",
"hash": "79779ed2a4f18bc80500110ea96afb50614e06d2c1e21aefc9fac5d82b030a32",
"hash_version": 1,
"url": "https://things5.s3.eu-west-1.amazonaws.com/cookbook-syncs/2729d40a-8e33-4ec6-aa8c-b1050c3f19a6/recipes/1.json"
}
]
}
Parameters
| name | description | example |
|---|---|---|
| manifest_version | version of the manifest format | 1 |
| cookbook_sync_id | id of this sync | |
| recipes | array of recipe entries | |
| recipes[].index | position of the recipe in the cookbook | 1 |
| recipes[].id | recipe template id | |
| recipes[].hash | content fingerprint of the recipe (lowercase hex SHA-256) | |
| recipes[].hash_version | algorithm version of hash | 1 |
| recipes[].url | HTTPS URL to download the recipe template |
Skipping unchanged recipes
hashis a content fingerprint of the recipe. Before downloadingurl, compare it against the recipe already stored on the device:
- same
hash→ the recipe is unchanged, skip the download;- different or missing
hash→ downloadurl;hash_versionthe device does not implement → treat the recipe as changed and downloadurl.Only
name,description,machine_model_id,phasesandmetadatacontribute to the hash. Editing who last changed a recipe or when does not change it, so a re-sync re-downloads only recipes whose content actually changed.
Recipe Template
The device downloads each recipe from its recipes[].url. The content fields are identical to the recipe objects v1 sends inline; v2 adds id, machine_model_id, hash and hash_version.
Representation
{
"id": "a43c7763-3b95-4707-9fac-86b48348f00c",
"index": 1,
"name": "Pollo con patate al cuore",
"description": "Recipe description",
"machine_model_id": "c8cfe490-843f-c4e5-0772-41849ae0af0f",
"hash": "79779ed2a4f18bc80500110ea96afb50614e06d2c1e21aefc9fac5d82b030a32",
"hash_version": 1,
"phases": [
{
"dosages": [
[
{
"name": "yeast",
"quantity": "5.5",
"metadata": [
{ "name": "type", "value": "1", "type": "integer" },
{ "name": "temperature", "value": "20", "type": "integer" }
]
}
]
],
"values": [
{ "name": "evaporator_fan_speed", "value": "4", "type": "integer" },
{ "name": "cell_temperature", "value": "-20", "type": "integer" }
]
},
{
"values": [
{ "name": "evaporator_fan_speed", "value": "2", "type": "integer" },
{ "name": "core_temperature", "value": "-5", "type": "integer" },
{ "name": "cell_temperature", "value": "-20", "type": "integer" }
]
},
{
"values": [
{ "name": "evaporator_fan_speed", "value": "1", "type": "integer" },
{ "name": "core_temperature", "value": "-5", "type": "integer" },
{ "name": "cell_temperature", "value": "-20", "type": "integer" }
]
},
{
"values": [
{ "name": "evaporator_fan_speed", "value": "0", "type": "integer" },
{ "name": "cell_temperature", "value": "-10", "type": "integer" }
]
}
],
"metadata": [
{ "name": "image_path", "value": "../images/fish.jpg", "type": "string" },
{ "name": "index_in_list", "value": "6", "type": "integer" }
]
}
Parameters
| name | description | example |
|---|---|---|
| id | recipe template id | |
| index | position of the recipe in the cookbook | 1 |
| name | recipe name | Pollo con patate al cuore |
| description | recipe description | |
| machine_model_id | machine model the recipe targets | |
| hash | content fingerprint (lowercase hex SHA-256) | |
| hash_version | algorithm version of hash | 1 |
| phases | the cooking program | |
| metadata | arbitrary recipe metadata |
Response has to be sent into the sync recipe templates response.
