Cookwala / SDK and scenarios / 056
Read the safety limits a device enforces locally
Safety limits live on the device and no request can raise them. Read the draft default pack the reference hub enforces, with its disclaimer, and the device's own stop and presence features.
Read first: /docs/CORE/ /docs/HUB/
Steps
Fourteen draft limits. The first cuts heat when frying oil passes 200 °C; each limit names its source.
safetyLimitsThe device declares presence detection and a stop control that works both locally and over the network.
capabilities
Outcome
You have read a limits pack and know it is a draft a maker must tighten from its own safety case. Next: scenario 053 reads the conformance claim.
Command line
cookwala hub --recipes examples --speed 200
curl -s http://localhost:7878/v1/safety-limits
cat profiles/core/safety-limits.default.jsonRecorded output
Status: ok
[1] safetyLimits: {"core": "0.2.0", "kind": "SafetyLimits", "id": "cookwala-default", "version": "0.2.0", "status": "draft", "limits": [{"id": "oil.max_temp", "kind": "max_temp", "action": "cut_heat", "message": "Cut heat above 200 °C: most cooking oils smoke and fire risk rises.", "source": "Common frying-oil smoke points; fire-safety practice", "appliesTo": {"medium": "oil", "ops": ["cw.op.fry", "cw.op.deep_fry"]}, "max": 200, "unit": "degC"}, {"id": "pan.max_surface", "kind": "max_temp", "action": "cut_heat", "message": "Cut heat above 280 °C pan surface (coatings degrade, oil ignites).", "source": "Cookware…
[2] capabilities: {"cookwala": "0.1.0", "actor": {"kind": "robot", "id": "robot:arm-1", "vendor": "Example Robotics", "model": "CounterArm 2"}, "roles": ["executor"], "location": {"zone": "counter-left", "mobile": false}, "capabilities": {"ops": [{"op": "cw.op.cut", "params": {"shape": ["dice", "slice", "mince", "julienne"]}, "ingredientClasses": ["cw.ing.class.vegetable_firm", "cw.ing.class.herb"], "reliability": 0.97}, {"op": "cw.op.crack", "reliability": 0.95}, {"op": "cw.op.transfer", "maxMassG": 3000}], "sensors": [{"sensor": "cw.sense.vision", "visionCues": ["cw.sense.translucent", "cw.sense.egg_whites_se…Code
Run: python scenarios/out/056-safety-limits-are-local-and-draft/python.py
# Scenario 056: Read the safety limits a device enforces locally
# Safety limits live on the device and no request can raise them. Read the draft default pack the reference hub enforces, with its disclaimer, and the device's own stop and presence features.
# 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: Fourteen draft limits. The first cuts heat when frying oil passes 200 °C; each limit names its source.
limits = c.safety_limits()
assert pick(limits, "id") == "cookwala-default", pick(limits, "id")
print("ok", "id", "=", "cookwala-default")
assert pick(limits, "status") == "draft", pick(limits, "status")
print("ok", "status", "=", "draft")
assert pick(limits, "limits.length") == 14, pick(limits, "limits.length")
print("ok", "limits.length", "=", 14)
assert pick(limits, "limits[0].id") == "oil.max_temp", pick(limits, "limits[0].id")
print("ok", "limits[0].id", "=", "oil.max_temp")
assert pick(limits, "limits[0].max") == 200, pick(limits, "limits[0].max")
print("ok", "limits[0].max", "=", 200)
assert pick(limits, "limits[0].action") == "cut_heat", pick(limits, "limits[0].action")
print("ok", "limits[0].action", "=", "cut_heat")
# Step 2: The device declares presence detection and a stop control that works both locally and over the network.
caps = c.capabilities()
assert pick(caps, "safety.presenceDetection") == True, pick(caps, "safety.presenceDetection")
print("ok", "safety.presenceDetection", "=", True)
assert pick(caps, "safety.emergencyStop") == "both", pick(caps, "safety.emergencyStop")
print("ok", "safety.emergencyStop", "=", "both")
print("scenario complete")