Compact CO2, temperature and humidity sensor for Home Assistant: ESP32-C3, Sensirion SCD41, 2" display, 3D-printed enclosure for flush wall boxes or desks. Browser installer, OTA updates, parametric Fusion CAD.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
A compact CO2, temperature and humidity monitor for Home Assistant.
It covers a flush wall box or stands on your desk.
English | Deutsch | Project page and browser installer檢視完整 README ↗A compact CO2, temperature and humidity monitor for Home Assistant. It covers a flush wall box or stands on your desk.
English | Deutsch | Project page and browser installer
flowchart LR
SCD41["SCD41<br>CO2 / temp / humidity"] -- I2C --> ESP["ESP32-C3 SuperMini<br>ESPHome"]
ESP -- SPI --> LCD["2" IPS display<br>320 x 240"]
ESP <-- "WiFi, native API" --> HA["Home Assistant"]
USB["USB-C 5 V<br>(wall box or surface cable)"] --> ESP
GH["GitHub releases"] -. "firmware update" .-> HA
Every 30 seconds (adjustable from 5 to 60 s) the SCD41 delivers a new reading. The ESP32-C3 updates the display, classifies the air quality against two thresholds (default 1000 and 1400 ppm) and reports everything to Home Assistant.
| Device | 79.6 × 69.8 × 24 mm (+ 3 mm rail) |
| Wall plate | 89.2 × 82 × 7 mm, slots for M4 screws 60 mm apart, also fits flush wall boxes Ø 68 mm |
| Display window | 41.8 × 31.6 mm, 320 × 240 px IPS |
| Sensor | Sensirion SCD41, 400 to 5000 ppm, ±(50 ppm + 5 % of reading) |
| Room size | one sensor per room; in open spaces up to about 500 m² (FAQ) |
| Power | 5 V via USB-C, about 0.5 W |
| Cable exit | back (90° USB-C adapter) or bottom (straight plug), same parts |
| Fasteners | 10 heat-set inserts M2 × 3 (OD 3.0 to 3.2), 10 screws M2 × 4 ISO 7380, 2 screws M4 for the wall |
| Print material | PETG (PLA possible), about 120 g |
Technical drawing (A3, ISO first angle): English PDF | German PDF
The total for one device is in the last row of the table. The links are suggestions, checked in October 2026; prices change often.
| Qty | Part | AliExpress | Amazon.de |
|---|---|---|---|
| 1 | Sensirion SCD41 breakout, 13.5 × 21.75 mm or 15 × 20 mm ² | 21.19 € | AliExpress only |
| 1 | ESP32-C3 SuperMini | 2.79 € | 4.30 € (2 pcs: 8.59 €) |
| 1 | Waveshare 2inch LCD Module (ST7789V, 240 × 320) | 12.49 € | 16.31 € |
| 10 | Heat-set insert M2 × 3, outer diameter 3.0 or 3.2 mm, length 3 mm | 2.39 € (50 pcs, OD 3.2) | 4.69 € (205 pcs, OD 3.0) |
| 10 | Button head screw M2 × 4, ISO 7380 | Amazon only | 4.79 € (60 pcs) |
| 1 | USB-C 90° adapter (plug to socket) for the cable to the back | Amazon only | 4.49 € |
² Shops often show a different board than the one they send. Measure it on arrival and print the matching carrier.
SCD41 boards come in different sizes. Only the small sensor carrier depends on the board: there is one for the 13.5 × 21.75 mm and one for the 15 × 20 mm board, for others enter six measurements in the online configurator and download the carrier. See measure your sensor.
Machine-readable: hardware/bom.yaml. This file is the only place for parts, prices and shop links; the table above and the project page are generated from it.
Print the two ready plates co2_wall_sensor_device.3mf and co2_wall_sensor_mounts.3mf (every part already in its print orientation, the device plate includes the desk stand: delete it for a wall mount) or the single files from cad/stl. Settings: docs/assembly.md.
Wire the modules according to docs/wiring.md and assemble them as described in docs/assembly.md. The 3D assembly guide shows every step: turn the device, take it apart, hide single parts (double-click) and see which part comes next.
Flash the firmware from your browser on the project page. To build it yourself: copy esphome/secrets.yaml.example to secrets.yaml, fill it in and install esphome/co2-wall-sensor.yaml with the ESPHome Builder (German interface: co2-wall-sensor-de.yaml).
Home Assistant discovers the device automatically.
| Entity | Type | Purpose |
|---|---|---|
| CO2, Temperature, Humidity | sensor | measurements every 30 s |
| Measuring interval, Smoothing | number, switch | 5 to 60 s (default 30 s), mean of two readings (default on) |
| Trend arrow from | number | change per hour that turns the arrow up or down (default 100 ppm/h) |
| CO2 trend, Ventilate in | sensor | ppm per hour, minutes until the red level |
| Air quality | text | Good, Moderate, Ventilate! |
| Outdoor temperature, Outdoor humidity | sensor | from Home Assistant, see outdoor values |
| Window hint | text | Open the window, Airing dries the air, Keep it shut, None; with a window contact: Airing for x min, Fresh air: close the window, Close the window: room cools down |
| CO2 threshold yellow / red | number | traffic light limits (default 1000 / 1400 ppm) |
| Display brightness | light | dim or switch off the display by hand |
| Night mode, Night from, Night until | switch, time | night schedule (default 22:00 to 06:00) |
| Display at night, Night brightness | select, number | dim (default 8 %) or switch off |
| Red warning at night | switch | the display wakes up while the CO2 level is red (not while a window is open) |
| Window hint on the display, Window symbol on the display, Outdoor value on the display | switch | show or hide them |
| Display upside down | switch | turns the picture by 180° if it stands on its head |
| Window hint from indoor temperature, Window hint: cooler outside by | number | default 24 °C and 3 °C |
| Fresh air below, Window warning below | number | with an open window: fresh air (default 700 ppm), room cools down (default 19 °C) |
| Temperature correction | number | self-heating at your wall: compare with a reference thermometer |
| Altitude above sea level |
All settings are kept after a power cut. Nothing has to be built yourself: the browser installer firmware has every setting.
The display shows the outdoor temperature under OUT, and the window hint compares inside and outside.
weather.forecast_home, the weather entity Home Assistant creates for your home location (integration Meteorologisk institutt (Met.no)).sensor.outdoor_temperature (humidity: sensor.outdoor_humidity). A few seconds later the display shows it. No new firmware needed.With a window contact the device knows when you are airing. The window symbol at the top is grey while the windows are shut. Open one and it turns blue, the hint line counts the minutes (Airing for 6 min), green tells you the air is fresh again (Fresh air: close the window, below 700 ppm) and orange that the room cools down too much (Close the window: room cools down, below 19 °C). While a window is open the red pill says Airing instead of Ventilate! and the red warning does not wake the display at night. Both thresholds are settings in Home Assistant, a switch hides the symbol. Every step with pictures: Home Assistant guide.
binary_sensor.co2_wall_sensor_window (binary_sensor.co2_wandsensor_fenster), exactly what the firmware listens to.window_entity in its device file.Ventilation reminder: a ready blueprint notifies your phone when the CO2 level stays high and the windows are shut, when the air is fresh again with the window open and when the room cools down. It takes the thresholds straight from the device.
More examples (automations, dashboard card) are in homeassistant/.
co2-wall-sensor/
├── cad/
│ ├── fusion/generate_enclosure/ Fusion script, the single source of truth for all geometry
│ ├── fusion/co2_wall_sensor.f3d Fusion archive of the assembly (with slider joint)
│ ├── 3mf/ print-ready plates
│ ├── step/ STEP of the full assembly
│ ├── stl/ single print files
│ └── build_info.json fingerprint of the parameters the print files were made from
├── docs/ assembly, wiring, Home Assistant guide, design notes, FAQ (German in docs/de)
│ ├── drawing/ technical drawing, PDF + PNG, EN and DE
│ └── images/ renders, animation, wiring diagram, display preview
├── esphome/
│ ├── co2-wall-sensor*.yaml device files: own build and browser installer, EN and DE
│ └── common/ shared firmware logic and network variants
├── hardware/bom.yaml bill of materials with shop links
├── homeassistant/ blueprint, automations and dashboard card (German in homeassistant/de)
├── site/ template of the project page
└── tools/ generators for drawing, wiring, preview, print plates, project page, checks
Every dimension is a Fusion user parameter.
cad/fusion/generate_enclosure. Run the script once.FIT for tighter or looser fits, the SCD_* values for a different sensor board (measure your sensor) or INSERT_HOLE_D for other inserts.EXPORT = True it writes new STL and STEP files and cad/build_info.json.pip install -r requirements.txt
python tools/drawing.py && python tools/build_3mf.py
python tools/wiring.py && python tools/display_preview.py
python tools/check_repo.py
The CI repeats all of this, compiles four firmware variants and checks that the print files belong to the committed parameters. More background: design notes and FAQ.
LCD_* and GLASS_*.Issues, ideas and pull requests are welcome, see CONTRIBUTING.md. Questions and photos of your build go to Discussions. Security issues: SECURITY.md.
Software and firmware: MIT. Hardware (enclosure, print files, drawing, bill of materials): CERN-OHL-P-2.0. © 2026 Tobias Schneider. Build it, adapt it, share it.
| 1 | USB power module for the flush wall box (installation by a qualified electrician), or any USB charger | Amazon only | 4.80 € (2 pcs: 9.59 €) |
| Silicone wire AWG 30 | Amazon only | 15.49 € (8 colours) |
| Total (one device, each part from this shop if it has it, otherwise from the other; without wire and filament) | 52.94 € | 60.57 € |
| number |
| pressure compensation of the CO2 value (default 300 m) |
| Calibrate SCD41 (fresh air 420 ppm) | button | forced recalibration in fresh air |
| Firmware | update | new releases (browser installer firmware) |
| WiFi signal, Uptime, Restart | diagnostic |