Data feeds
A sensor needs something to sense. In Lab mode that something is a data feed: a small pipeline attached to each reading a part makes. You choose where the value comes from and set two or three knobs; the simulator supplies the realism.
source → shapers (optional, yours) → sensor model (automatic, from the datasheet)
The feed lives in the inspector, under Datafeed (or Response model for output parts). Each part declares the fields it reads — a DHT22 has temperature and humidity, a soil sensor has moisture — and each field gets its own source, knobs, preview and shaper stack.
The pipeline in practice
For one field you choose:
- Source — where the true value comes from. The dropdown lists only the sources that make sense: the environment source only appears for a field with a physical quantity, for instance.
- Knobs — two to four settings for that source: a wave's period, a random walk's swing, a recording's channel.
- Preset — a named configuration you can apply in one click.
- Shapers — an optional stack of transformations applied top to bottom.
- The sensor model — applied automatically at the end, from the part's datasheet. The badge beside the field name spells it out, e.g.
±0.5 °C · 0.1 °C steps · τ 2 s.
The preview below the controls draws the next minute, hour or day of this field, computed with the same seed and the same world the simulation will use, so you can see what a knob does before running anything.
Tick Ideal sensor (at the top of the section) to bypass the sensor model entirely: the part reports the true value, with no noise, offset or lag. That is what the judge uses for most objective sensors, and it is handy when you are debugging your code rather than your sensor.
Sources
| Source | Knobs | Use it for |
|---|---|---|
| Environment | Zone | A value that is consistent with every other sensor: sun, weather, rooms. Needs a field with a physical quantity. |
| Manual | Value | A slider you move by hand. While the simulation runs, dragging it moves the live value and releasing saves it. |
| Constant | Value | A fixed reading for tests. |
| Wave | Shape (sine, square, triangle, saw), centre, amplitude, period | A predictable test signal. |
| Daily cycle | Minimum, maximum, peak hour | A day/night swing without any location. |
| Random walk | Mean, typical swing, wander time | Slow, drifting values that stay near a mean. |
| Random events | Normally, during an event, events per hour, event length | Occasional changes: motion, leaks, spikes. |
| Daily schedule | Times = values (e.g. 08:00=21, 18:00=17), step or linear | A timetable: heating on at 8, off at 18. |
| Formula | Formula of t (s), hour, day | Anything you can write down: 20 + 5sin(2pi*t/60). It is parsed safely — no Python is run. |
| Recording | Recording, channel, speed, loop or hold at the end | Replaying a run you recorded with the Recorder. |
| This device | Input, scale, offset | Real inputs from this computer or phone. |
The This device source can read the microphone level (mic.db), device tilt (tilt.pitch, tilt.roll) and motion (motion.x/y/z), pointer position (pointer.x/y), and the ambient light sensor where the browser has one (light.lux). Only the inputs your feeds actually use are started, and the browser asks for permission when the run starts. If permission is denied or an input is unavailable, that field reads as a failed sensor instead of stopping the simulation.
Presets
Built-in presets describe air temperature, so they appear on °C fields and cover a room, the greenhouse, a fridge, a server rack, a failing sensor and so on. Choosing one writes a whole source configuration (and its shapers) into the field.
You can also build a configuration you like and click Save as preset: it is stored on the server against the part type, so it follows you between boards. Saving needs an account and a backend; built-ins work with no server at all. Presets never store replayed sample data.
Shapers
Shapers bend the true value before the sensor model sees it. Add as many as you need, reorder them with the arrows, and remove them with ✕; each one has its own knobs.
| Shaper | What it does |
|---|---|
| Offset | Adds a constant. |
| Gain | Multiplies by a factor. |
| Clamp | Limits the value to a range. |
| Quantize | Rounds to a step. |
| Noise | Adds jitter of a given standard deviation (σ). |
| Drift | Adds a slow error, in units per hour. |
| Spikes | Occasional large deviations. |
| Dropouts | Occasional outages for a fixed length. |
| Gets stuck | Freezes the reading after a time. |
| Lag | First-order smoothing with a time constant τ. |
| Delay | Delays the signal by a number of seconds. |
A failing sensor is usually just Spikes + Dropouts + Drift on a healthy source.
The automatic sensor model
Even with a perfect source, a real part does not report the true value. The model runs last and uses only the datasheet's measurement entry:
- Calibration offset — a fixed per-unit error derived from the accuracy, seeded so that this particular part is always a little high or a little low, like the real one on your desk.
- Read noise — Gaussian noise on every reading (by default a quarter of the accuracy).
- Resolution — readings are quantised to the part's steps.
- Range — readings saturate at the part's measuring range instead of going past it.
- Response time — a first-order lag, so the part does not jump instantly to a new value.
The badge next to the field name summarises this from the datasheet. Because the source, the shapers, the world and the model are all deterministic for a given project seed, the same board run twice produces the same values — which is what makes objectives reproducible.
Live weather and recordings
Live weather is the one part of the world that comes from outside. Set the World dialog's weather to live, and the page asks the backend for the forecast at your latitude and longitude; the backend proxies and caches the provider, refreshed every 15 minutes. Without a backend the choice is disabled and procedural weather is used.
A Recording field replays data you captured with the Recorder instrument (or a dataset saved on the server). Before the run starts, the page loads the recording's samples and hands them to the simulation, so nothing is fetched while it runs. Set the recording id and channel (leave the channel blank for the first one), a replay speed, and what happens at the end: loop or hold the last value. If the recording cannot be loaded, the field reads as a failed sensor — visible in your program as a NaN/error rather than silence.