Diese Seite wurde maschinell übersetzt und wurde noch nicht von einer Person überprüft. Englisch ist die Referenz; Korrekturen auf GitHub sind willkommen. GitHub

Cookwala / SDK und Szenarien / 020

Check a simmer trace against its envelope: inside, left it, missed the target

An envelope is the safe band for the medium. The check tolerates the warm-up, then requires every reading to stay in the band and, once the recipe target is reached, near it.

Zielgruppe: developer · Ziel: Roboter für Menschen · Level: beginner

Zuerst lesen: /docs/CORE/ /docs/QUICKSTART/

Schritte

  1. Warm-up to 88, then 92 and 94 degC with a target of 94 plus or minus 3: inside the band, target held. checkEnvelope

  2. The same pot reaches 99 degC: that is a boil, not a simmer. checkEnvelope

  3. Inside the band but it drifted away from the target after reaching it. checkEnvelope

  4. The band itself, from the vocabulary. getOps

Ergebnis

You can tell an envelope violation from a missed target, and you know the warm-up is not a violation. Next: scenario 021 moves the boiling band with altitude.

Kommandozeile

printf '[{"t": 0, "tempC": 60}, {"t": 30, "tempC": 88}, {"t": 60, "tempC": 92}, {"t": 90, "tempC": 94}]' > trace.json && cookwala envelope cw.op.simmer trace.json --target 94 --tolerance 3
printf '[{"t": 0, "tempC": 60}, {"t": 30, "tempC": 90}, {"t": 60, "tempC": 94}, {"t": 90, "tempC": 99}]' > trace.json && cookwala envelope cw.op.simmer trace.json --target 94 --tolerance 3

Aufgezeichnete Ausgabe

Status: ok

[1] checkEnvelope: {"envelopeOk": true, "targetOk": true, "reason": "ok"}
[2] checkEnvelope: {"envelopeOk": false, "targetOk": false, "reason": "left_envelope"}
[3] checkEnvelope: {"envelopeOk": true, "targetOk": false, "reason": "missed_target"}
[4] 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…

Code

Ausführen: python scenarios/out/020-simmer-trace-inside-and-outside/python.py

# Scenario 020: Check a simmer trace against its envelope: inside, left it, missed the target
# An envelope is the safe band for the medium. The check tolerates the warm-up, then requires every reading to stay in the band and, once the recipe target is reached, near it.
# 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: Warm-up to 88, then 92 and 94 degC with a target of 94 plus or minus 3: inside the band, target held.
ok = c.check_envelope("cw.op.simmer", [{"t": 0, "tempC": 60}, {"t": 30, "tempC": 88}, {"t": 60, "tempC": 92}, {"t": 90, "tempC": 94}], {"value": 94, "tolerance": 3})
assert pick(ok, "envelopeOk") == True, pick(ok, "envelopeOk")
print("ok", "envelopeOk", "=", True)
assert pick(ok, "targetOk") == True, pick(ok, "targetOk")
print("ok", "targetOk", "=", True)
assert pick(ok, "reason") == "ok", pick(ok, "reason")
print("ok", "reason", "=", "ok")

# Step 2: The same pot reaches 99 degC: that is a boil, not a simmer.
left = c.check_envelope("cw.op.simmer", [{"t": 0, "tempC": 60}, {"t": 30, "tempC": 90}, {"t": 60, "tempC": 94}, {"t": 90, "tempC": 99}], {"value": 94, "tolerance": 3})
assert pick(left, "envelopeOk") == False, pick(left, "envelopeOk")
print("ok", "envelopeOk", "=", False)
assert pick(left, "targetOk") == False, pick(left, "targetOk")
print("ok", "targetOk", "=", False)
assert pick(left, "reason") == "left_envelope", pick(left, "reason")
print("ok", "reason", "=", "left_envelope")

# Step 3: Inside the band but it drifted away from the target after reaching it.
missed = c.check_envelope("cw.op.simmer", [{"t": 0, "tempC": 86}, {"t": 30, "tempC": 94}, {"t": 60, "tempC": 88}], {"value": 94, "tolerance": 3})
assert pick(missed, "envelopeOk") == True, pick(missed, "envelopeOk")
print("ok", "envelopeOk", "=", True)
assert pick(missed, "targetOk") == False, pick(missed, "targetOk")
print("ok", "targetOk", "=", False)
assert pick(missed, "reason") == "missed_target", pick(missed, "reason")
print("ok", "reason", "=", "missed_target")

# Step 4: The band itself, from the vocabulary.
ops = c.get_ops()
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.medium") == "water", pick(ops, "entries[32].envelope.medium")
print("ok", "entries[32].envelope.medium", "=", "water")
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)

print("scenario complete")

scenarios/020-simmer-trace-inside-and-outside.json

Zurück: 019 Weiter: 021