Node-RED MQTT Joins: Define When a Multi-Topic Sensor Record Is Complete

A joined MQTT object can contain three fields while one required sensor is missing. For a Node-RED collector, define the required topic names and the meaning of a collection before choosing Join’s count. Otherwise, a working flow can store a misleading equipment record without producing a processing error.

This walkthrough pins Node-RED 5.0.8 and uses synthetic telemetry. Its timelines are expected outcomes derived from source inspection, not executed Node-RED or broker tests. The goal is a reviewable aggregation contract for independently arriving measurements.

Choose the record the consumer actually needs

A latest-state display can legitimately combine the newest available temperature, pressure and humidity. A production-cycle record needs evidence that those observations belong to the intended cycle. These are different database schemas, even when both contain three numbers.

Write the chosen contract beside the flow. For the example below, one collection begins with the first accepted arrival and closes after either all three required topics arrive or one second elapses. It is an arrival-window record. It does not claim synchronized physical acquisition or membership in a machine cycle.

Define the expected set as lab/mixer/temperature, lab/mixer/pressure and lab/mixer/humidity. Attach each observation’s gateway arrival time and, where supplied, its source timestamp and source sequence inside the payload before joining. Give those fields distinct names so a later reader can tell what was actually observed.

Configure the object and its membership boundary

The official Join cookbook shows manual object construction using msg.topic as the key. Its example collects distinct topics and keeps the most recent value for each. The 5.0.8 editor definition exposes count, timeout and accumulation separately.

For this proposed fixture, record every relevant setting: custom/manual mode, build object, property msg.payload, key msg.topic, count 3, timeout 1 second, accumulation disabled and useparts false. Keep this Join dedicated to one mixer’s accepted streams; sharing it across machines would require another explicit grouping design.

Place an exact-topic membership filter before Join. Reject unknown topics to a diagnostic path. A wildcard MQTT subscription can be useful for receiving data, but it should not silently become the definition of which measurements complete a record.

In the pinned runtime’s object-build branch, the incoming key replaces that property’s value and the count is the number of object keys. Count three therefore identifies a quantity, without identifying the required names.

Two-topic arrival timeline produces incomplete timeout output; an unexpected vibration topic can satisfy count three without humidity.
Original conceptual collection-policy diagram. Times and values are hypothetical; no runtime result.

Original collection-policy diagram. Topic suffixes and values are abbreviated; per-observation metadata is omitted. Times are hypothetical; no runtime measurement is shown.

Walk through a silent-source fixture

Start with empty Join state. The following arrival offsets are relative to the first accepted message:

  • At 0 ms, temperature supplies value 20.
  • At 100 ms, temperature supplies value 21.
  • At 150 ms, pressure supplies value 100.
  • Humidity remains silent throughout the one-second collection.

At 150 ms, the expected payload contains two properties: temperature with value 21 and pressure with value 100, each retaining its own observation metadata. The temperature repeat replaces a value; it does not supply the missing humidity member.

With no further accepted arrivals, the timer closes the collection at approximately one second after its start. Scheduling can delay actual delivery. The expected output still contains only the temperature and pressure keys. Classify it as incomplete and record humidity in a missing-topic list. Do not invent a humidity value or label an earlier collection’s value as newly received.

Now repeat from empty state and introduce lab/mixer/vibration at 200 ms. Without the membership filter, three distinct keys satisfy the count and produce an early object lacking humidity. With the filter, vibration never enters Join; the two-key collection reaches its timeout. This negative case distinguishes an exact membership rule from a count-only test.

Validate the emitted object before storing it

At the next boundary, compare the object’s own keys with the expected set. Compute both missing and unexpected names. A complete arrival-window record requires neither list to contain an entry, plus whatever payload-validity and age checks the application specified. Checking only object length recreates the original defect downstream.

Store incomplete records separately or mark their quality explicitly according to the consumer contract. An explicit missing value can be useful, but preserve the missing-topic reason and avoid passing it through arithmetic as zero. Record the collection definition alongside its identifier so reporting code knows whether it is analyzing latest state, an arrival window or a verified source cycle.

Keep collection lifetime explicit

In 5.0.8, completeSend removes the group when accumulation is disabled. This supports a fresh group after the fixture’s count or timeout output. Turning accumulation on changes the state lifecycle; review the resulting age semantics before reusing the flow for historical records.

A humidity message arriving after timeout belongs to a subsequent arrival collection under this design. It cannot retroactively complete the stored record without a separate, explicitly designed correction policy. If machine-cycle alignment is required, carry a source cycle identifier with a producer identity and group by that contract instead of inferring a cycle from topic names.

The acceptance fixture should capture input messages, exact Join settings and emitted payloads for the repeated-topic, silent-topic, unexpected-topic and late-arrival cases. Success means the consumer can explain why each record is complete or incomplete. A successful Join output alone leaves that question unanswered.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *