Sensors & recipes
A recipe is the unit of knowledge that connects “what do you want to know” to “what do
you install and how do you configure it.” Each of the 43 shipped recipes covers one goal
(for example energy, vibration-health, part-count, air-leaks) on one machine class
(for example injection_moulding, cnc, conveyor), and is rendered as its own page in the
recipe gallery (the Recipes section of the sidebar), generated from recipes/*/*.yaml.
What a recipe contains
Section titled “What a recipe contains”| Field | What it tells you |
|---|---|
physics | why the signal behaves the way it does, in plain terms |
sensor | the generic sensor spec — kind, unit, range — not a specific brand |
example_parts | two or three illustrative vendor/part examples, so you know what class of part to shop for |
mounting / wiring | how to install it on the actual machine |
sample_rate_hz, edge_hardware, processing | how the raw signal is sampled and conditioned before it reaches a detector |
detector | which detector binds to this signal and its default parameters |
validation | a check you can run with a handheld instrument to confirm the install is sane |
cost_band | a range, not a quote — see below |
safety_notes | lockout/tagout and PPE guidance for the install itself |
difficulty, install_downtime_min, pros, cons | what the install actually costs you in time and trade-offs |
Reading cost_band
Section titled “Reading cost_band”Every recipe’s cost figure is a low/high range in a stated currency, derived from the
example_parts listed on that same recipe — never a single fixed price and never a quote
for ReduceWaste itself. Treat it as “this class of part has historically cost roughly this
much,” not as a vendor quote. If you need a firm number, price the specific part you intend
to buy.
Vendor neutrality
Section titled “Vendor neutrality”example_parts exists to make the generic spec concrete, not to recommend a vendor. Any part
that meets the sensor spec (signal kind, unit, range) works. Nothing in a recipe or in
ReduceWaste itself is tied to a specific manufacturer.
From recipe to live signal
Section titled “From recipe to live signal”- A recipe is matched to an asset during planning, based on its machine class and your stated goal.
- The sensor is installed per the recipe’s mounting/wiring guidance (by a qualified electrician where the safety notes call for it).
- The edge reader is configured with the resulting tag, under the path convention
area/line/cell/asset/signal(see Quick start for a worked example using the demo plant). - The recipe’s
detectorblock becomes that signal’s detector configuration, so the detector starts learning a baseline as soon as live data arrives.
For the glossary of terms used across recipes (duty cycle, baseline, excess-over-baseline, and so on), see the in-product glossary; the same terms are used consistently across every recipe and every detector.
Reference firmware (ESP32)
Section titled “Reference firmware (ESP32)”ReduceWaste ships a reference ESP-IDF v5.3 firmware for the edge reader itself —
services/rw-edge/firmware/sensor-node — covering the three signal kinds most recipes
call for: a pulse contact, a 4-20mA current loop, and a 0-10V analog input.
It is read-only OT by design: the node only measures and publishes, the same INV-4
guarantee every other adapter in rw-edge holds to.
Topic and payload contract
Section titled “Topic and payload contract”One MQTT publish per signal, at the same UNS path every recipe uses:
rw/v1/{site}/{area}/{line}/{cell}/{asset}/{signal}{"ts": 1700000000123456789, "v": 12.375, "q": 0, "seq": 42}ts is real wall-clock nanoseconds (via SNTP), v is the engineering-unit reading, q is
0 good / 1 uncertain / 2 bad, and seq is a per-signal counter that resets on reboot.
Every path segment and each channel’s signal name is a per-node setting (Kconfig or an NVS
override), never hardcoded into the firmware image.
Wiring and calibration at a glance
Section titled “Wiring and calibration at a glance”| Channel | Hardware | Default calibration |
|---|---|---|
| Pulse | ESP32 PCNT with a glitch filter, on a Kconfig-selected GPIO | total count since boot |
| 4-20mA loop | 165Ω shunt → ADC1 oneshot (4mA = 0.66V, 20mA = 3.3V) | gain 1.0 / offset 0.0 |
| 0-10V | 3:1 resistor divider → ADC1 oneshot (10V → 3.33V) | gain 1.0 / offset 0.0 |
Calibration (Rule 10) is gain + offset per channel, stored in NVS and overridable at
runtime without reflashing; see the firmware’s own README.md for exact resistor values,
GPIO defaults, and the full wiring diagram notes.
Networking, store-and-forward, and build
Section titled “Networking, store-and-forward, and build”Wi-Fi is the default transport; an optional wired Ethernet path (WIZnet W5500 over SPI, or LAN8720 over RMII) is selectable in Kconfig. MQTT5 over TLS is published via esp-mqtt. If the broker is unreachable, samples queue into a flash-persisted ring buffer and flush in order on reconnect. There is deliberately no OTA code path — nodes are deployed air-gapped, per INV-3 — firmware updates are a physical reflash.
Build with the official Docker image:
docker run --rm -v $PWD/services/rw-edge/firmware/sensor-node:/p -w /p \ espressif/idf:v5.3 idf.py set-target esp32 buildSee services/rw-edge/firmware/sensor-node/README.md for the full wiring/calibration
reference, the esp32-s3 build command, and the host-native test instructions.