Project · Smart room · Safety
One panel that watches the whole room
Four cheap parts cover a room completely: a DHT22 for climate, a PIR for motion, an MQ-2 for gas and smoke, and a 2-channel relay for the light and fan. One ESP32 ties them into a safety panel with an alarm chain — badge, buzzer, event log, auto-venting — that you control from a dashboard the chip serves itself.
The parts and their quirks
| Part | Role | Quirk to know |
|---|---|---|
| DHT22 | temp + humidity | one reading per 2 s, single-wire protocol |
| PIR (HC-SR501) | motion | holds its output for a retrigger window — treat it as one |
| MQ-2 | gas / smoke | needs a warm-up burn-in and per-unit calibration |
| Relay 2ch | light + fan | opto-isolated boards want 5 V; check IN polarity |
| Buzzer | local alarm | active buzzers just need a GPIO high |
The alarm chain — priorities, not spaghetti
The panel has one status, and gas always wins: GAS! > Motion > All clear. A gas hit sounds the buzzer, force-starts the fan to vent, and writes the event; motion just flips the badge and logs. That priority logic is five lines:
// Alarm chain: gas beats motion; the buzzer follows the gas state, fan auto-vents.
bool gasBad = gas > 350; // real: calibrate to your MQ-2
if (gasBad && roomState != 2 && evlog) evlog->print("GAS/SMOKE - venting");
roomState = gasBad ? 2 : (motion ? 1 : 0);
alarmOut = gasBad;
if (gasBad) fan = true; // auto-vent on gas
// PIR: the module holds its output ~3 s per trigger — treat it as a window.
motion = millis() < motionUntil; The dashboard
Two pages: Room (readings + status + log) and Control (light, fan, alarm state).
The dht22 and mq2 presets pick the right widgets and ranges on their own:
dash.layout("Room", RICON_HOME);
dash.sensor("dht22", &temp, &hum); // temp gauge + humidity metric
dash.sensor("mq2", &gas); // smoke/LPG gauge with the right range
dash.badge("Status", &roomState).labels("All clear", "Motion", "GAS!");
dash.led("Motion", &motion); // PIR state, live
evlog = &dash.log("Events", 6);
dash.layout("Control", RICON_BULB);
dash.toggle("Light", &light); // relay channel 1
dash.toggle("Fan", &fan); // relay channel 2
dash.led("Alarm", &alarmOut); // buzzer output
dash.beginAP("RisalDash-Room", "12345678"); The shipped example (examples/04_Templates/RoomMonitor) runs with no hardware — the fake MQ-2 occasionally “smells smoke” and the PIR fires at random, so you can watch the whole chain trip: badge → buzzer → log → fan. Then wire the real parts and delete the fakes. Every widget doubles as an MCP tool, so an AI agent can ask “is anyone in the room?” or turn the fan on — that's the AI-agent pattern.
Related builds
Only need intrusion? The shipped MotionSecurity template adds zones and an arming switch. Only gas safety? GasSafety does MQ-2 + MQ-7 with trip LEDs. Whole apartment? SmartHome scales the same pattern to scenes and rooms — this room panel is the single-room distillation of all three.
Watch the alarm chain fire on fakes tonight — wire the room at the weekend.