Cookwala / SDK and scenarios / 006
List the demo devices, the operation vocabulary and the recipes a hub can plan
Three catalog calls give you everything a dry run works with: capability documents by id, the fifty-seven operations with their envelopes and sensor ladders, and the recipe ids the hub holds.
Read first: /docs/CORE/ /docs/QUICKSTART/
Steps
Six capability documents: the example arm and the five presets of the home-page demo.
getDevicesThe operation vocabulary. Deep frying has a one-rung ladder; simmering is water at 85 to 96 degC.
getOpsThe nine example recipes, sorted by id.
listRecipes
Outcome
You can look up any operation envelope by index or id and any device by its file name. Next: scenario 009 asks the sensor ladder which rung a device can satisfy.
Command line
curl -s http://localhost:7878/v1/tools/devices
curl -s http://localhost:7878/v1/tools/vocab/ops
curl -s http://localhost:7878/v1/tools/recipesRecorded output
Status: ok
[1] getDevices: {"devices": {"demo-arm": {"cookwala": "0.1.0", "actor": {"kind": "robot", "id": "demo:arm", "vendor": "Cookwala demo presets", "model": "Counter robot arm (cuts, cracks, mixes, moves)"}, "roles": ["executor"], "location": {"zone": "kitchen", "mobile": false}, "capabilities": {"ops": [{"op": "cw.op.cut"}, {"op": "cw.op.crack"}, {"op": "cw.op.transfer"}, {"op": "cw.op.mix"}, {"op": "cw.op.whisk"}, {"op": "cw.op.wash"}, {"op": "cw.op.drain"}, {"op": "cw.op.crush"}, {"op": "cw.op.grate"}, {"op": "cw.op.layer"}, {"op": "cw.op.garnish"}, {"op": "cw.op.form"}], "sensors": [{"sensor": "cw.sense.vision…
[2] getOps: {"name": "ops", "version": "0.2.0", "entries": [{"id": "cw.op.dispense", "label": {"en": "Dispense / measure", "ar": "قياس وإضافة"}, "definition": "Measure an ingredient by mass, volume or count and add it to a target.", "classes": ["cw.opfamily.handle"], "paramsSchema": {"type": "object", "properties": {"precision": {"type": "number"}}}, "sensors": ["cw.sense.mass"], "links": {"ieee1872": "IEEE 1872.1-2024 Task (to be mapped)"}}, {"id": "cw.op.transfer", "label": {"en": "Transfer", "ar": "نقل"}, "definition": "Move food or a vessel's contents from one place to another.", "classes": ["cw.opfam…
[3] listRecipes: {"recipes": ["basbousa", "ful-medames", "kofta-oven", "koshari", "lentil-soup", "molokhia", "rice-vermicelli", "salata-baladi", "shakshuka"]}Code
Run: python scenarios/out/006-list-devices-and-ops/python.py
# Scenario 006: List the demo devices, the operation vocabulary and the recipes a hub can plan
# Three catalog calls give you everything a dry run works with: capability documents by id, the fifty-seven operations with their envelopes and sensor ladders, and the recipe ids the hub holds.
# Run a hub first: python hub/cookwala_hub.py --recipes examples
import json, os
from cookwala.client import CookwalaClient, CookwalaProblem
def load(path):
with open(path, encoding="utf-8") as f:
return json.load(f)
def pick(obj, path):
for part in path.replace("]", "").replace("[", ".").split("."):
obj = obj[int(part)] if part.isdigit() else (len(obj) if part == "length" else obj.get(part))
return obj
c = CookwalaClient(os.environ.get("COOKWALA_HUB", "http://localhost:7878"))
# Step 1: Six capability documents: the example arm and the five presets of the home-page demo.
devices = c.get_devices()
assert pick(devices, "devices.demo-oven.actor.kind") == "appliance", pick(devices, "devices.demo-oven.actor.kind")
print("ok", "devices.demo-oven.actor.kind", "=", "appliance")
assert pick(devices, "devices.robot-arm.capabilities.ops.length") == 3, pick(devices, "devices.robot-arm.capabilities.ops.length")
print("ok", "devices.robot-arm.capabilities.ops.length", "=", 3)
assert pick(devices, "devices.demo-fryer-robot.capabilities.sensors.length") == 6, pick(devices, "devices.demo-fryer-robot.capabilities.sensors.length")
print("ok", "devices.demo-fryer-robot.capabilities.sensors.length", "=", 6)
assert pick(devices, "devices.demo-hob-robot-basic.capabilities.sensors.length") == 1, pick(devices, "devices.demo-hob-robot-basic.capabilities.sensors.length")
print("ok", "devices.demo-hob-robot-basic.capabilities.sensors.length", "=", 1)
# Step 2: The operation vocabulary. Deep frying has a one-rung ladder; simmering is water at 85 to 96 degC.
ops = c.get_ops()
assert pick(ops, "name") == "ops", pick(ops, "name")
print("ok", "name", "=", "ops")
assert pick(ops, "version") == "0.2.0", pick(ops, "version")
print("ok", "version", "=", "0.2.0")
assert pick(ops, "entries.length") == 57, pick(ops, "entries.length")
print("ok", "entries.length", "=", 57)
assert pick(ops, "entries[30].id") == "cw.op.deep_fry", pick(ops, "entries[30].id")
print("ok", "entries[30].id", "=", "cw.op.deep_fry")
assert pick(ops, "entries[30].envelope.sensorLadder.length") == 1, pick(ops, "entries[30].envelope.sensorLadder.length")
print("ok", "entries[30].envelope.sensorLadder.length", "=", 1)
assert pick(ops, "entries[32].id") == "cw.op.simmer", pick(ops, "entries[32].id")
print("ok", "entries[32].id", "=", "cw.op.simmer")
assert pick(ops, "entries[32].envelope.tempC.min") == 85, pick(ops, "entries[32].envelope.tempC.min")
print("ok", "entries[32].envelope.tempC.min", "=", 85)
assert pick(ops, "entries[32].envelope.tempC.max") == 96, pick(ops, "entries[32].envelope.tempC.max")
print("ok", "entries[32].envelope.tempC.max", "=", 96)
# Step 3: The nine example recipes, sorted by id.
recipes = c.list_recipes()
assert pick(recipes, "recipes.length") == 9, pick(recipes, "recipes.length")
print("ok", "recipes.length", "=", 9)
assert pick(recipes, "recipes[0]") == "basbousa", pick(recipes, "recipes[0]")
print("ok", "recipes[0]", "=", "basbousa")
assert pick(recipes, "recipes[8]") == "shakshuka", pick(recipes, "recipes[8]")
print("ok", "recipes[8]", "=", "shakshuka")
print("scenario complete")