ESPHome's development branch has a new component for DFRobot's "Factory Calibrated Electrochemical Gas Sensor" series, models SEN0465 to SEN0476. Pull request #20880 by tzabbi was merged on 17 October 2026 after review by bdraco, and its documentation went into the next branch of esphome.io the same day. Both target ESPHome 2026.11, the version the development branch is building now.
Twelve boards, one protocol
All twelve share one signal conversion board and one protocol. Only the probe changes, so one component covers them and the model key picks the gas:
| Model | Gas | Model | Gas |
|---|---|---|---|
| SEN0465 | Oxygen (O2, in %) | SEN0471 | Nitrogen dioxide (NO2) |
| SEN0466 | Carbon monoxide (CO) | SEN0472 | Ozone (O3) |
| SEN0467 | Hydrogen sulfide (H2S) | SEN0473 | Hydrogen (H2) |
| SEN0468 | Chlorine (Cl2) | SEN0474 | Hydrogen chloride (HCl) |
| SEN0469 | Ammonia (NH3) | SEN0475 | Hydrogen fluoride (HF) |
| SEN0470 | Sulfur dioxide (SO2) | SEN0476 | Phosphine (PH3) |
All models except the oxygen one report in ppm. The model also sets the number of decimals and the device class, so a SEN0466 shows up in Home Assistant as a carbon monoxide sensor. Each board also reports the temperature from its own on-board sensor.
That is different hardware from the MiCS-5524 added a day earlier, whose single analog output reacts to several gases at once. Here each probe measures one gas and the board sends the result digitally.
I2C or UART
A SEL DIP switch on the board picks the bus: 0 for I2C, 1 for UART. That gives two platforms, dfrobot_sen0465_i2c and dfrobot_sen0465_uart. The default I2C address is 0x77, and the A0 and A1 switches select anything from 0x74 to 0x77. The sensor knows other address groups between 0x60 and 0x7F, but ESPHome cannot change the group; that takes DFRobot's Arduino library. UART is fixed at 9600 baud, 8N1, and ESPHome rejects a config with other settings or without both a TX and an RX pin.
At boot ESPHome puts the sensor into passive mode, where it only answers requests, waits one second, sets the alarm and takes the first reading. Each step gets three tries. When a reading gets no answer, a wrong answer or a bad checksum, the sensors go to unknown instead of keeping a stale value. The default update_interval is 60 s.
Temperature compensation and the alarm pin
Electrochemical probes drift with temperature. With temperature_compensation: true, ESPHome corrects the concentration with the formulas from DFRobot's library and the board temperature. Outside the range those formulas cover, the reading becomes NaN with a warning, where DFRobot's library would return 0. The option is not offered for oxygen, which has no formula, or for hydrogen, where the vendor formula divides by 0.74 × T + 0.007 and gives nonsense below 20 °C.
An alarm: block programs the threshold of the board's ALA output, tripping above it (high, the default) or below it (low). Without the block, ESPHome switches the alarm off at boot. The alarm state cannot be read over I2C or UART, so to see it in Home Assistant you wire ALA to a GPIO and add a GPIO binary sensor. The board compares the threshold with its own uncompensated reading, which means the alarm can trip at a slightly different value from the one ESPHome shows.
Tested on one CO board
The author ran a SEN0466 on an ESP32-C6 over both buses. CO rose when incense smoke reached the probe, and over UART 17 readings in a row arrived without a checksum error. The ALA pin itself and temperature compensation were covered only by a test with an emulated UART.