Esta página fue traducida por una máquina y aún no ha sido revisada por una persona. El inglés es la referencia; las correcciones son bienvenidas en GitHub. GitHub

Cookwala / SDK y escenarios / 034

The fryer robot plans koshari with every heat step verified by a sensor

With estimates forbidden, a robot that has a pan thermometer, a liquid thermometer and an oil thermometer still plans all twenty steps of koshari, none by estimate and none by a person. Then check the recipe's own frying target against the envelope.

Audiencia: robot maker · Objetivo: Ayudar a acabar con el hambre, Robots para las personas · Nivel: beginner

Leer primero: /docs/CORE/ /docs/QUICKSTART/

Pasos

  1. Estimates forbidden: boiling by liquid thermometer, heating by pan thermometer, deep frying by oil thermometer. dryRun

  2. The recipe asks for oil at 175 plus or minus 10 degC and limits each batch to 130 g. getRecipe

  3. A trace that holds the recipe target passes the envelope and the target. checkEnvelope

  4. Twenty steps, the deep fry by the device.

Resultado

You have the sensor list a koshari robot needs to run with no estimates and no person doing a step, and the target it must hold. Next: scenario 022 shows the limit above that target.

Línea de comandos

cookwala dryrun examples/koshari.cookwala.json --device examples/capabilities/demo-fryer-robot.json --human-present --no-model
curl -s http://localhost:7878/v1/tools/recipes/koshari
printf '[{"t": 0, "tempC": 160}, {"t": 30, "tempC": 172}, {"t": 60, "tempC": 176}, {"t": 90, "tempC": 174}]' > trace.json && cookwala envelope cw.op.deep_fry trace.json --target 175 --tolerance 10

Salida grabada

Estado: ok

[1] dryRun: {"state": "accepted", "plan": [{"node": "n1", "op": "cw.op.boil", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n2", "op": "cw.op.simmer", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n3", "op": "cw.op.drain", "by": "device", "verifiedBy": "time", "rung": "time"}, {"node": "n4", "op": "cw.op.boil", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n5", "op": "cw.op.boil", "by": "device", "verifiedBy": "sensor", "rung": "cw.sense.liquid_temp"}, {"node": "n6", "op": "cw.op.drain", "by": "d…
[2] getRecipe: {"$schema": "https://cookwala.ai/v1/schemas/recipe.schema.json", "cookwala": "0.2.0", "id": "example-koshari", "revision": 1, "updated": "2026-10-04", "verification": {"level": "V1", "evidence": {"simulatorRuns": 0, "humanReviews": 1, "fieldReports": 0}, "reviewedBy": "cookwala.ai editorial (structure only)", "notes": "Example recipe written to exercise the standard: structured steps, end conditions, hazards and critical control points. Not simulated and not field-verified; values are typical home-cooking values, not measurements."}, "dish": {"names": {"en": "Koshari", "ar": "كشري"}, "cuisine"…
[3] checkEnvelope: {"envelopeOk": true, "targetOk": true, "reason": "ok"}

Código

Ejecutar: python scenarios/out/034-fryer-robot-without-estimates/python.py

# Scenario 034: The fryer robot plans koshari with every heat step verified by a sensor
# With estimates forbidden, a robot that has a pan thermometer, a liquid thermometer and an oil thermometer still plans all twenty steps of koshari, none by estimate and none by a person. Then check the recipe's own frying target against the envelope.
# 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: Estimates forbidden: boiling by liquid thermometer, heating by pan thermometer, deep frying by oil thermometer.
plan = c.dry_run(recipe_id="koshari", device_id="demo-fryer-robot", human_present=True, allow_model=False)
assert pick(plan, "state") == "accepted", pick(plan, "state")
print("ok", "state", "=", "accepted")
assert pick(plan, "plan.length") == 20, pick(plan, "plan.length")
print("ok", "plan.length", "=", 20)
assert pick(plan, "plan[0].rung") == "cw.sense.liquid_temp", pick(plan, "plan[0].rung")
print("ok", "plan[0].rung", "=", "cw.sense.liquid_temp")
assert pick(plan, "plan[6].rung") == "cw.sense.pan_surface_temp", pick(plan, "plan[6].rung")
print("ok", "plan[6].rung", "=", "cw.sense.pan_surface_temp")
assert pick(plan, "plan[13].rung") == "cw.sense.oil_temp", pick(plan, "plan[13].rung")
print("ok", "plan[13].rung", "=", "cw.sense.oil_temp")
assert pick(plan, "plan[10].rung") == "cw.sense.vision", pick(plan, "plan[10].rung")
print("ok", "plan[10].rung", "=", "cw.sense.vision")

# Step 2: The recipe asks for oil at 175 plus or minus 10 degC and limits each batch to 130 g.
koshari = c.get_recipe("koshari")
assert pick(koshari, "process.nodes[13].op") == "cw.op.deep_fry", pick(koshari, "process.nodes[13].op")
print("ok", "process.nodes[13].op", "=", "cw.op.deep_fry")
assert pick(koshari, "process.nodes[13].params.target.value") == 175, pick(koshari, "process.nodes[13].params.target.value")
print("ok", "process.nodes[13].params.target.value", "=", 175)
assert pick(koshari, "process.nodes[13].params.target.tolerance") == 10, pick(koshari, "process.nodes[13].params.target.tolerance")
print("ok", "process.nodes[13].params.target.tolerance", "=", 10)
assert pick(koshari, "process.nodes[13].params.batchMaxG") == 130, pick(koshari, "process.nodes[13].params.batchMaxG")
print("ok", "process.nodes[13].params.batchMaxG", "=", 130)

# Step 3: A trace that holds the recipe target passes the envelope and the target.
trace = c.check_envelope("cw.op.deep_fry", [{"t": 0, "tempC": 160}, {"t": 60, "tempC": 172}, {"t": 120, "tempC": 176}, {"t": 180, "tempC": 174}], {"value": 175, "tolerance": 10})
assert pick(trace, "envelopeOk") == True, pick(trace, "envelopeOk")
print("ok", "envelopeOk", "=", True)
assert pick(trace, "targetOk") == True, pick(trace, "targetOk")
print("ok", "targetOk", "=", True)
assert pick(trace, "reason") == "ok", pick(trace, "reason")
print("ok", "reason", "=", "ok")

# Step 4: Twenty steps, the deep fry by the device.
assert pick(plan, "plan[13].by") == "device", pick(plan, "plan[13].by")
print("ok", "plan[13].by", "=", "device")
assert pick(plan, "plan[13].verifiedBy") == "sensor", pick(plan, "plan[13].verifiedBy")
print("ok", "plan[13].verifiedBy", "=", "sensor")

print("scenario complete")

scenarios/034-fryer-robot-without-estimates.json

Anterior: 033 Siguiente: 035