Feeds third-party BBQ probes into a pellet grill's wired probe jacks by presenting the resistance a real PT1000 RTD would show at that temperature. The grill sees an ordinary wired probe, so its display, app, target-temp alarms and Keep Warm all work with no protocol reversing involved. Pluggable probe sources: ThermoWorks RFX (via ThermoWorks Cloud), MEATER (community-derived BLE decode), a synthetic simulator for hardware-free development, and a Combustion stub. Two safety invariants are load-bearing: - Stale, missing or implausible readings drive the channel cold, never hot. A stuck-hot channel could convince the grill a cook finished early. - Unimplemented sources raise rather than returning plausible numbers, since the grill acts on these values. Cloud sources are dated by the cloud's own timestamp rather than by fetch time, because ThermoWorks serves a dead probe's last value with a fresh 200. Co-Authored-By: Claude Opus 5 <[email protected]>
smokescreen
Feed third-party BBQ probes (MEATER, ThermoWorks, Combustion) into a pellet grill's wired probe jacks, so they show up as native probes on the grill display and in the vendor app — with working target-temp alarms and Keep Warm.
Developed and tested against a Traeger Ironwood (2022 touchscreen WiFire), but the technique is just PT1000 emulation, so it should carry to any grill using the same 3.5 mm PT1000 jacks — Pit Boss, Camp Chef, GMG and friends.
The name is the mechanism: the grill is looking at a probe that isn't there.
How it works
your probes ──BLE──> Raspberry Pi ──I²C──> AD5272 rheostat ──3.5mm──> Traeger jacks 1 & 2
The Ironwood's wired jacks take PT1000 RTDs — 1000 Ω at 0 °C, ~3.85 Ω/°C, a published standard curve. So instead of breaking Traeger's wireless pairing, we just be a PT1000: read your probe over BLE, compute the resistance a real PT1000 would have at that temperature, and present it to the jack.
No protocol to reverse, nothing to re-break after a firmware update, and the grill's own logic works because as far as it knows, nothing unusual happened.
Why not MITM the wireless probes — and why one nRF52840 dongle can't anyway — is in docs/PROTOCOL_NOTES.md.
Start here
Before writing code or buying parts, do Step 0 in docs/HARDWARE.md: put a plain 1.2 kΩ resistor in a 3.5 mm plug, plug it into jack 1, and check the grill reads ~127 °F. That one experiment validates this entire design in ten minutes with a multimeter and a junk-drawer resistor.
Quick start
python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
Run the whole pipeline with no hardware at all — simulated probes, no I²C writes:
cp config.example.yaml config.yaml && .venv/bin/smokescreen run --dry-run
jack1=20.3C/1079ohm [Simulated probe 1] jack2=17.2C/1067ohm [Simulated probe 2]
The PT1000 reference table, for bench work with a multimeter:
.venv/bin/smokescreen table
On the Pi, with hardware wired and calibrated:
.venv/bin/smokescreen run
Adding a probe vendor
Subclass ProbeSource, emit ProbeReading objects, register it in
sources/__init__.py. Nothing else changes — the router and the PT1000
emulator never learn what hardware produced a number.
| Source | Status |
|---|---|
simulator |
Works. Synthetic cook curve with a stall, for development |
thermoworks |
RFX via ThermoWorks Cloud. Needs pip install '.[thermoworks]' |
meater |
Implemented from community reverse engineering — verify on the bench |
combustion |
Stub. Open published spec, easiest to finish |
With more probes than jacks — four RFX probes into two jacks — list what's visible and pin the two you want:
.venv/bin/smokescreen discover
Unimplemented sources raise rather than returning plausible-looking numbers. The grill acts on these values, so a driver that silently invents data would be worse than one that refuses to start.
Safety
Stale, missing, or implausible readings drive the channel cold, never hot. A stuck-hot channel could convince the grill a cook finished early; a stuck-cold one can only look obviously wrong. Details and the reasoning are in docs/HARDWARE.md.
This is a hobby project driving a fire with reverse-engineered numbers. Keep a real probe in the cook until you have several successful runs behind you.
Layout
src/smokescreen/
pt1000.py IEC 60751 curve math — the part that must be right
models.py ProbeReading, ChannelState
router.py which probe drives which jack
bridge.py orchestration loop
sources/ probe backends (add vendors here)
outputs/ rheostat driver + PT1000 emulator
docs/HARDWARE.md wiring, BOM, calibration, Step 0
docs/PROTOCOL_NOTES.md what we know per vendor, and how much to trust it