pyrtan / sourcev0.13.0 · main

pyrtan / examples / room-temperature / room-temperature.toml

2,453 bytes · last changed 2026-10-26 in Watches and growing from a gap: trees that run when something speaks, and the branch a gap asks for drafted by rules; release 0.9.0

1# The temperature a room's sensor last published, over MQTT. A queue node
2# subscribes to a topic and waits for one message (an act node publishes
3# one). The broker must be in `hosts`, the topic under `topics`; both are
4# checked at run time when they come from the sentence.
5
6name = "room-temperature"
7version = 2
8namespace = "pyrtan"
9description = "The temperature a room's sensor last published, over MQTT."
10tags = ["home", "mqtt"]
11license = "MIT"
12hosts = ["broker.local"]
13topics = ["home/+/temperature"]
14start = "wait"
15
16[[triggers]]
17pattern = "[what's the] temperature in the {room:word}"
18[[triggers]]
19pattern = "how warm is the {room:word}"
20
21[inputs.room]
22type = "str"
23default = "kitchen"
24pattern = "^[a-z0-9-]+$"
25
26# Also on its own: every reading the kitchen's sensor publishes runs the
27# tree (the run then takes the next message on the topic; a watch on the
28# same topic as the tree reads is the simplest shape, not the only one).
29[[watches]]
30queue = { url = "mqtt://broker.local", topic = "home/kitchen/temperature" }
31inputs = { room = "kitchen" }
32
33[nodes.wait]
34kind = "observe"
35queue = { url = "mqtt://broker.local", topic = "home/{{ inputs.room }}/temperature" }
36into = "q" # state.q = { url, topic, received, message = { topic, body, json }, body, json }
37timeout = 15
38retries = 0
39next = "got"
40
41[nodes.got]
42kind = "decide"
43on = "q.received"
44branches = [{ when = { eq = true }, then = "reading" }, { else = "quiet" }]
45
46[nodes.reading]
47kind = "decide"
48on = "q.json.temperature"
49branches = [
50 { when = { lt = 16 }, then = "cold" },
51 { when = { lt = 26 }, then = "fine" },
52 { when = { gte = 26 }, then = "warm" },
53]
54
55[nodes.cold]
56kind = "done"
57say = "{{ inputs.room }}: {{ state.q.json.temperature }}°C, cold."
58output = { room = "{{ inputs.room }}", temperature = "{{ state.q.json.temperature }}", topic = "{{ state.q.message.topic }}" }
59
60[nodes.fine]
61kind = "done"
62say = "{{ inputs.room }}: {{ state.q.json.temperature }}°C."
63output = { room = "{{ inputs.room }}", temperature = "{{ state.q.json.temperature }}", topic = "{{ state.q.message.topic }}" }
64
65[nodes.warm]
66kind = "done"
67say = "{{ inputs.room }}: {{ state.q.json.temperature }}°C, warm."
68output = { room = "{{ inputs.room }}", temperature = "{{ state.q.json.temperature }}", topic = "{{ state.q.message.topic }}" }
69
70[nodes.quiet]
71kind = "fail"
72reason = "no-reading"
73say = "Nothing on home/{{ inputs.room }}/temperature within 15 s; is the sensor publishing?"