Cette page a été traduite par une machine et n'a pas encore été révisée par une personne. L'anglais est la référence ; les corrections sont les bienvenues sur GitHub. GitHub

Cookwala / SDK et scénarios / 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.

Audience: developer · Objectif: Des robots pour les gens · Niveau: beginner

Lire d'abord: /docs/CORE/ /docs/QUICKSTART/

Étapes

  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

Résultat

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.

Ligne de commande

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

Sortie enregistrée

Statut: 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

Exécuter: 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

Précédent: 019 Suivant: 021