Skip to content

Smart Thermostat

The Smart Thermostat task is the canonical introductory example: a sensor stream in, a cooling command out, and a Hysteresis node in the middle that keeps the relay from chattering when the temperature sits on the boundary. Five nodes end-to-end — the simplest task that tells a complete “rules engine replacement” story.

A temperature sensor publishes readings to the demo slot. We want a cooling controller that:

  • Turns cooling ON when the temperature rises above 24 °C.
  • Turns cooling OFF only after it drops below 22 °C — not at 23.99 °C.
  • Emits nothing while the temperature sits inside the dead band, so consumers aren’t spammed with “no change” messages.

Summary

Task namedemo-Thermostat01
Input topicdemo/showcase/thermostat/01/in
Output topicdemo/showcase/thermostat/01/out
Operations usedmqtt.MqttTrigger, core.JsonParser, core.Hysteresis, core.Boolean, mqtt.MqttAction
MqttTrigger ─► JsonParser ─► Hysteresis ─► Boolean ─► MqttAction
  • JsonParser pulls /temp out of the incoming payload.
  • Hysteresis is configured with Threshold High = 24.0, Threshold Low = 22.0. It outputs true when the input rises above 24, false when it falls below 22, and stops the execution path on every reading in between — so downstream nodes run only on state changes.
  • Boolean is an AND over a single Data input (which is the identity for one boolean) and its output format is set to String, with the true text COOL ON and the false text COOL OFF. The node serves as a typed projection from the Hysteresis bool directly to the string the dashboard wants to see — no Const/Condition/Report wiring required.
  • MqttAction publishes the string payload to the output topic.

Every Node that carries On Error leaves it at Stop this branch — the default. Error handling is the subject of later Thermostat variants; this task is the on-ramp where the happy path is the whole story.

Input

Topic: demo/showcase/thermostat/01/in

{"temp": 24.5}

Output

Topic: demo/showcase/thermostat/01/out

COOL ON

A representative sequence:

Reading (/temp)Hysteresis edgeOutput
23.0none (first value inside dead band)nothing
24.5false → trueCOOL ON
23.5none (above low threshold, still high)nothing
21.5true → falseCOOL OFF
  1. Make sure the demo slot is running — either on the public demo server or in your own Nonbl instance with an equivalent task defined.

  2. Subscribe to the output topic in one shell:

    Terminal window
    mosquitto_sub -h <broker> -t demo/showcase/thermostat/01/out
  3. Publish a few readings from another shell:

    Terminal window
    mosquitto_pub -h <broker> -t demo/showcase/thermostat/01/in -m '{"temp":23.0}'
    mosquitto_pub -h <broker> -t demo/showcase/thermostat/01/in -m '{"temp":24.5}'
    mosquitto_pub -h <broker> -t demo/showcase/thermostat/01/in -m '{"temp":23.5}'
    mosquitto_pub -h <broker> -t demo/showcase/thermostat/01/in -m '{"temp":21.5}'

    You should see COOL ON for reading 24.5 and COOL OFF for 21.5. The other two readings sit inside the dead band and are silently absorbed.

Dead-banded control is the textbook fix for the “relay flapping on the threshold” problem. Expressing it as a single node — instead of a pair of Compares plus state juggling — keeps the graph readable and makes the dead band visible at a glance. Hysteresis also is one of the few operations whose output is preserved across restarts, so the controller resumes in the same state it left off in.