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 / 029
missing_capability: what an appliance cannot do, and what accepted means when a person does the rest
A device that lacks an operation is refused alone and named at the first missing step. With a person present every missing step is assigned to the person, so accepted means a plan exists, not that the appliance does much of it.
Lire d'abord: /docs/CORE/ /docs/QUICKSTART/
Étapes
The oven cannot grate an onion: refused at n1 with the reason spelled out.
dryRunThe counter arm washes and drains the rice, then cannot heat a pan: two steps planned, refused at n3.
dryRunWith a person: accepted. The person grates, cuts, mixes and forms; the oven preheats and bakes.
dryRunA salad on an oven with a person present is also accepted, and every one of the nine steps is the person's. Read the plan, not only the state.
dryRun
Résultat
You know how to read a missing_capability refusal and why a product page should count the steps the device does, not the recipes it accepts. Next: scenario 030 shows the refusal no person can lift.
Ligne de commande
cookwala dryrun examples/kofta-oven.cookwala.json --device examples/capabilities/demo-oven.json
cookwala dryrun examples/rice-vermicelli.cookwala.json --device examples/capabilities/demo-arm.json
cookwala dryrun examples/kofta-oven.cookwala.json --device examples/capabilities/demo-oven.json --human-present
cookwala dryrun examples/salata-baladi.cookwala.json --device examples/capabilities/demo-oven.json --human-presentSortie enregistrée
Statut: ok
[1] dryRun: {"state": "refused", "refusal": {"reason": "missing_capability", "node": "n1", "detail": "device cannot perform cw.op.grate and no person is present to do it"}, "plan": []}
[2] dryRun: {"state": "refused", "refusal": {"reason": "missing_capability", "node": "n3", "detail": "device cannot perform cw.op.heat and no person is present to do it"}, "plan": [{"node": "n1", "op": "cw.op.wash", "by": "device", "verifiedBy": "time", "rung": "time"}, {"node": "n2", "op": "cw.op.drain", "by": "device", "verifiedBy": "time", "rung": "time"}]}
[3] dryRun: {"state": "accepted", "plan": [{"node": "n1", "op": "cw.op.grate", "by": "human", "verifiedBy": "human"}, {"node": "n2", "op": "cw.op.cut", "by": "human", "verifiedBy": "human"}, {"node": "n3", "op": "cw.op.crush", "by": "human", "verifiedBy": "human"}, {"node": "n4", "op": "cw.op.mix", "by": "human", "verifiedBy": "human"}, {"node": "n5", "op": "cw.op.form", "by": "human", "verifiedBy": "human"}, {"node": "n6", "op": "cw.op.chill", "by": "human", "verifiedBy": "human"}, {"node": "n7", "op": "cw.op.heat", "by": "device", "verifiedBy": "model", "rung": "model"}, {"node": "n8", "op": "cw.op.bake…
[4] dryRun: {"state": "accepted", "plan": [{"node": "n1", "op": "cw.op.wash", "by": "human", "verifiedBy": "human"}, {"node": "n8", "op": "cw.op.wash", "by": "human", "verifiedBy": "human"}, {"node": "n2", "op": "cw.op.cut", "by": "human", "verifiedBy": "human"}, {"node": "n9", "op": "cw.op.cut", "by": "human", "verifiedBy": "human"}, {"node": "n3", "op": "cw.op.cut", "by": "human", "verifiedBy": "human"}, {"node": "n4", "op": "cw.op.whisk", "by": "human", "verifiedBy": "human"}, {"node": "n5", "op": "cw.op.mix", "by": "human", "verifiedBy": "human"}, {"node": "n6", "op": "cw.op.chill", "by": "human", "ve…Code
Exécuter: python scenarios/out/029-refusal-missing-capability/python.py
# Scenario 029: missing_capability: what an appliance cannot do, and what accepted means when a person does the rest
# A device that lacks an operation is refused alone and named at the first missing step. With a person present every missing step is assigned to the person, so accepted means a plan exists, not that the appliance does much of 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: The oven cannot grate an onion: refused at n1 with the reason spelled out.
ovenAlone = c.dry_run(recipe_id="kofta-oven", device_id="demo-oven", human_present=False)
assert pick(ovenAlone, "state") == "refused", pick(ovenAlone, "state")
print("ok", "state", "=", "refused")
assert pick(ovenAlone, "refusal.reason") == "missing_capability", pick(ovenAlone, "refusal.reason")
print("ok", "refusal.reason", "=", "missing_capability")
assert pick(ovenAlone, "refusal.node") == "n1", pick(ovenAlone, "refusal.node")
print("ok", "refusal.node", "=", "n1")
assert pick(ovenAlone, "refusal.detail") == "device cannot perform cw.op.grate and no person is present to do it", pick(ovenAlone, "refusal.detail")
print("ok", "refusal.detail", "=", "device cannot perform cw.op.grate and no person is present to do it")
# Step 2: The counter arm washes and drains the rice, then cannot heat a pan: two steps planned, refused at n3.
armAlone = c.dry_run(recipe_id="rice-vermicelli", device_id="demo-arm", human_present=False)
assert pick(armAlone, "state") == "refused", pick(armAlone, "state")
print("ok", "state", "=", "refused")
assert pick(armAlone, "refusal.reason") == "missing_capability", pick(armAlone, "refusal.reason")
print("ok", "refusal.reason", "=", "missing_capability")
assert pick(armAlone, "refusal.node") == "n3", pick(armAlone, "refusal.node")
print("ok", "refusal.node", "=", "n3")
assert pick(armAlone, "plan.length") == 2, pick(armAlone, "plan.length")
print("ok", "plan.length", "=", 2)
# Step 3: With a person: accepted. The person grates, cuts, mixes and forms; the oven preheats and bakes.
ovenWithPerson = c.dry_run(recipe_id="kofta-oven", device_id="demo-oven", human_present=True)
assert pick(ovenWithPerson, "state") == "accepted", pick(ovenWithPerson, "state")
print("ok", "state", "=", "accepted")
assert pick(ovenWithPerson, "plan.length") == 10, pick(ovenWithPerson, "plan.length")
print("ok", "plan.length", "=", 10)
assert pick(ovenWithPerson, "plan[0].by") == "human", pick(ovenWithPerson, "plan[0].by")
print("ok", "plan[0].by", "=", "human")
assert pick(ovenWithPerson, "plan[7].by") == "device", pick(ovenWithPerson, "plan[7].by")
print("ok", "plan[7].by", "=", "device")
# Step 4: A salad on an oven with a person present is also accepted, and every one of the nine steps is the person's. Read the plan, not only the state.
salad = c.dry_run(recipe_id="salata-baladi", device_id="demo-oven", human_present=True)
assert pick(salad, "state") == "accepted", pick(salad, "state")
print("ok", "state", "=", "accepted")
assert pick(salad, "plan.length") == 9, pick(salad, "plan.length")
print("ok", "plan.length", "=", 9)
assert pick(salad, "plan[0].by") == "human", pick(salad, "plan[0].by")
print("ok", "plan[0].by", "=", "human")
assert pick(salad, "plan[8].by") == "human", pick(salad, "plan[8].by")
print("ok", "plan[8].by", "=", "human")
print("scenario complete")