# 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](docs/PROTOCOL_NOTES.md#the-wireless-traeger-probes--the-road-not-taken). ## Start here **Before writing code or buying parts**, do [Step 0 in docs/HARDWARE.md](docs/HARDWARE.md#step-0--prove-the-concept-for-0-before-buying-anything): 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 ```bash 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: ```bash 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: ```bash .venv/bin/smokescreen table ``` On the Pi, with hardware wired and calibrated: ```bash .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: ```bash .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](docs/HARDWARE.md#failure-behaviour). 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 ```